嘲弄JVM的压缩哎呀

Gee*_*eek 17 java jvm memory-management

所以我理解现在默认情况下在HotSpot VM中启用了压缩oops.从Java SE 6u23开始,它通过VM选项支持此功能-XX:+UseCompressedOops.我知道它允许有效的CPU缓存利用率,因为CPU缓存可以容纳大量的引用,而不是它们必须处理64位大小的引用.但我不明白的是,如何只使用32位JVM可以解决多达2 64个地址.

为了简化问题,我们如何仅使用2位来处理多达2个4的内存地址?这种地址方案可能的编码/解码是什么?

Ste*_*n C 29

有关压缩oops的详细说明,请参阅John Rose @ Oracle 中的"Hotspot JVM中的压缩oops"一文.

TL; DR版本是:

  • 在现代计算机体系结构中,内存地址是字节地址,
  • Java对象引用是指向单词1开头的地址,
  • 在64位机器上,字对齐意味着对象引用/地址的底部3位为零2
  • 因此,通过将地址向右移3位,我们可以将64位地址的35位"压缩"为32位字,
  • 并且,可以通过将3位向左移位来完成解压缩,这将3个零位置回,
  • 35位寻址允许我们使用在64位计算机上适合32位(半)字的压缩oops来表示最多32 GB堆内存的对象指针.

请注意,这适用于64位JVM.我们仍然需要能够处理包含(最多)32 GB堆1的内存,这意味着64位硬件地址(在现代CPU /计算机体系结构上).

另请注意,这样做会受到轻微的惩罚; 即在常规和压缩引用之间转换所需的转换指令.然而,另一方面是消耗的实际内存较少3,因此内存缓存通常更有效.

1 - 这是因为现代计算机体系结构针对字对齐的内存访问进行了优化.

2 - 这假设您没有用于-XX:ObjectAlignmentInBytes将对齐从其默认(和最小)值8字节增加.

3 - 实际上,内存节省是特定于应用程序的.它取决于平均对象对齐浪费,参考与非参考字段的比率等.如果考虑调整对象对齐,它会变得更复杂.


为了简化问题,我们如何仅使用2位来处理多达2个4个存储器地址?这种地址方案可能的编码/解码是什么?

您不能寻址2个4字节地址.但是,您可以使用2位字地址寻址2 2个字地址(假设32位字).如果您可以假设所有字节地址都是字对齐的,那么您可以将4位字节地址压缩为2位字地址,方法是将其移位2位.

  • 我不遵循“在 64 位机器上,这意味着地址的底部 3 位为零”的逻辑。为什么引用指向单词的开头会导致低 3 位全为 0 的情况? (3认同)
  • 因为现代计算机体系结构是字节寻址的. (2认同)

Enn*_*oji 9

它不适用于32位JVM.这是为了减轻64位JVM中发生的额外开销.我认为Oracle的页面解释得很好:

压缩的哎呀

压缩的oops表示托管指针(在JVM软件中的许多但不是所有位置)作为来自64位Java堆基址的32位对象偏移量.因为它们是对象偏移而不是字节偏移,所以它们可以用于处理多达40亿个对象(不是字节),或者堆大小最多大约32千兆字节.要使用它们,必须将它们缩放8倍并添加到Java堆基址以查找它们引用的对象.

资源