java usecompressedclasspointers,java-8 – java8 -XX:UseCompressedOops -XX:ObjectAlignmentInBytes = 16...

我将尝试对Alexey提供的答案进行一点延伸,因为有些事情可能并不明显.

根据Alexey的建议,如果我们在OpenJDK的源代码中搜索分配了压缩klass位移值的位置,我们将在metaspace.cpp中找到以下代码:

void Metaspace::set_narrow_klass_base_and_shift(address metaspace_base, address cds_base) {

// some code removed

if ((uint64_t)(higher_address - lower_base) <= UnscaledClassSpaceMax) {

Universe::set_narrow_klass_shift(0);

} else {

assert(!UseSharedSpaces, "Cannot shift with UseSharedSpaces");

Universe::set_narrow_klass_shift(LogKlassAlignmentInBytes);

}

我们可以看到,类移位可以是0(或基本上没有移位)或3位,因为LogKlassAlignmentInBytes是globalDefinitions.hpp中定义的常量:

const int LogKlassAlignmentInBytes = 3;

所以,你的排名的答案:

I was really expecting to both be “4-bit shift”. Why they are not?

是ObjectAlignmentInBytes对元空间中的压缩类指针对齐没有任何影响,它始终是8bytes.

当然,这个结论并没有回答这个问题:

“为什么在使用-XX:ObjectAlignmentInBytes = 16和-XX:UseCompressedClassPointers时,狭窄的klass移位变为零?另外,如果堆是4GB或更多,那么如果没有移动JVM如何用32位引用引用类空间?”

我们已经知道类空间是在java堆之上分配的,并且可以达到3G的大小.考虑到这一点,让我们做一些测试. -XX:UseCompressedOops -XX:默认情况下启用UseCompressedClassPointers,因此我们可以消除这些以简洁.

测试1:默认值 – 8个字节对齐

$java -XX:ObjectAlignmentInBytes=8 -XX:+UnlockDiagnosticVMOptions -XX:+PrintCompressedOopsMode -version

heap address: 0x00000006c0000000, size: 4096 MB, zero based Compressed Oops

Narrow klass base: 0x0000000000000000, Narrow klass shift: 3

Compressed class space size: 1073741824 Address: 0x00000007c0000000 Req Addr: 0x00000007c0000000

请注意,堆从虚拟空间中的地址0x00000006c0000000开始,大小为4GBytes.让我们从堆开始的位置跳过4Gbytes,然后我们就到了类空间开始的地方.

0x00000006c0000000 + 0x0000000100000000 = 0x00000007c0000000

类空间大小为1Gbyte,所以让我们跳过另一个1Gbyte:

0x00000007c0000000 + 0x0000000040000000 = 0x000000

I was really expecting to both be "4-bit shift". Why they are not?00000

我们降到32Gbytes以下.通过3位类空间移位,JVM能够引用整个类空间,尽管它处于极限(有意).

测试2:16字节对齐

java -XX:ObjectAlignmentInBytes=16 -XX:+UnlockDiagnosticVMOptions -XX:+PrintCompressedOopsMode -version

heap address: 0x0000000f00000000, size: 4096 MB, zero based Compressed Oops

Narrow klass base: 0x0000001000000000, Narrow klass shift: 0

Compressed class space size: 1073741824 Address: 0x0000001000000000 Req Addr: 0x0000001000000000

这次我们可以观察到堆地址不同,但让我们尝试相同的步骤:

0x0000000f00000000 + 0x0000000100000000 = 0x0000001000000000

这次堆空间在64GBytes虚拟空间边界下结束,类空间分配在64Gbyte边界以上.由于类空间只能使用3位移位,JVM如何引用位于64Gbyte以上的类空间?关键是:

Narrow klass base: 0x0000001000000000

JVM仍然使用32位压缩指针作为类空间,但是当对它们进行编码和解码时,它总是将0x0000001000000000 base添加到压缩引用而不是使用移位.请注意,只要引用的内存块低于4Gbytes(32位引用的限制),此方法就可以工作.考虑到类空间可以具有最大3G字节,我们可以轻松地在限制范围内.

3:16字节对齐,引脚堆基址为8g

$java -XX:ObjectAlignmentInBytes=16 -XX:HeapBaseMinAddress=8g -XX:+UnlockDiagnosticVMOptions -XX:+PrintCompressedOopsMode -version

heap address: 0x0000000200000000, size: 4096 MB, zero based Compressed Oops

Narrow klass base: 0x0000000000000000, Narrow klass shift: 3

Compressed class space size: 1073741824 Address: 0x0000000300000000 Req Addr: 0x0000000300000000

在此测试中,我们仍然保留-XX:ObjectAlignmentInBytes = 16,但还要求JVM使用-XX:HeapBaseMinAddress = 8g JVM参数在虚拟地址空间的第8 GByte分配堆.类空间将在虚拟地址空间中以第12 GByte开始,并且3位移位足以引用它.

希望这些测试及其结果能够回答这个问题:

“Why when using -XX:ObjectAlignmentInBytes=16 with -XX:+UseCompressedClassPointers the narrow klass shift becomes zero? Also, without shifting how can the JVM reference the class space with 32-bit references, if the heap is 4GBytes or more?”

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值