我很难理解压缩指针在Java 19中是如何工作的,请帮助。
在java 11中,对于小于32 GB的堆,引用大小为4(压缩指针),对于更大的堆,引用大小为8。在Java 19中,即使对于更大的堆,引用大小也为4字节(如何??)。
详细信息:
Java版本:开放式数据库Java 11.0.12和开放式数据库Java 19.0.1
命令行:
-XX:+解锁实验性虚拟机选项-XX:+使用EpsilonGC-Xlog:gc -Xlog:gc+堆+coops -Xms 41 g-Xmx 41 g-XX:+始终预接触
-XX:+解锁实验性虚拟机选项-XX:+使用EpsilonGC-Xlog:gc -Xlog:gc+堆+coops -Xms 31 g-Xmx 31 g-XX:+始终预接触
代码:https://github.com/cornelcreanga/fun/blob/master/src/main/java/com/ccreanga/various/RandomAllocate.java-代码取自https://shipilev.net/jvm/anatomy-quarks/23-compressed-references/
在Java 11/19中运行这段代码,可以看到,对于大于32 GB的堆,Java 19中的内存大小比Java 11中的小。对于较小的堆,大小几乎相同。
- 谢谢-谢谢
1条答案
按热度按时间up9lanfz1#
您正在查看
byte[]
数组和java.lang.Object
示例的布局。它们都不包含对堆内对象的引用。您所看到的差异在于 class pointer 的大小,它并不指向堆内存中的某个位置。但是由于历史原因,
-XX:+UseCompressedClassPointers
选项与-XX:+UseCompressedOops
选项绑定在一起。因此,当堆大小不允许压缩对象指针时,压缩类指针也会被禁用。JDK-8241825, Make compressed oops and compressed class pointers independent解决了这个问题,JDK 15已经解决了这个问题。
所以当我把你的程序改成
然后用41GB的堆运行它,我得到
JDK 15之前的版本和
JDK 15或更高版本。
这种差异显然是由类指针和填充引起的,但是在每个JVM版本中,三个对象引用需要24个字节。