Java中的对象引用有多大?它包含的是什么信息?

作为一个程序员,我认为这些看起来像“在地址1a234552的java.lang.Object”或类似的东西像s

 Object s = "hello"; 

它是否正确? 因此,所有的引用都是固定的大小?

虽然在许多VM上,引用的大小是原生指针大小(即32位JVM为32位,64位JVM为64位),但这并不能保证 – 特别是HotSpot现在或将要支持“压缩糟糕“ ,这是64位JVM中的32位引用。 (这并不意味着每个参考文献都是压缩的 – 阅读链接的文章以获取更多信息,同时也有大量博客文章。)

作为对另一个评论的回应,请注意引用本身通常只是解决对象本身的一种方式。 无论是否是直接内存指针,其目标都是获取对象的数据。 这基本上是真正重要的。 如果有一些“备用”位(例如它是一个64位引用,并且不需要所有的宽度来表示对象的位置),那么虚拟机就可以使用这些数据来获取其他信息,例如types,这可能允许一些优化。 (有关更多详细信息,请参阅Tom的评论。)

对象本身包含types信息(可能是对Class实例的引用,或类似的东西 – 我不太清楚),以及头部中其他必需的“东西”,然后到达该对象的用户数据。

它不是JLS或JVM规范的一部分,但实际上它将是一个地址:32位CPU上的32位,64位的64位。

pqism:好吧,因为编译之后我们不再关心声明的types了吗?

我们很在乎。 这就是为什么Class对象在那里。 事实上,从其他答案你可以看到,我们关心的运行时types足以优化我们与他们合作的方式,把部分types信息引用。

大多数人倾向于将对象的引用看作C语言类的内存指针。 虽然这在技术上不正确,但大多数实现都将其作为指针来实现。 例如,在压缩对象指针的情况下,JVM仅存储64位平台上的64位指针的位3至34。 其他实现也可以select使用不同的scheme:引用可以是包含所有对象的指针数组的索引。

对象引用的大小取决于JVM和机器体系结构。 一般来说,在32位机器上是32位,而在64位机器上是64位。 不过,我认为OpenJDK 7 JVM将支持“压缩指针”,这将在64位机器上节省一些空间。

关于对象types的信息存储在对象本身中; 也就是说,如果您遵循指向对象的32位或64位指针(或者更可能是句柄),则会find另一个指向Class实例的指针,该实例描述types以及对象的数据字段。