UseCompressedOops在jdk-13和jdk-15中使用压缩类指针



我无意中在Java 15中遇到了一个我没有意识到的变化。假设我有一个非常简单的问题:一个由3个整数组成的数组的大小是多少?为此,我使用JOL。代码相当琐碎:

import org.openjdk.jol.info.ClassLayout;
import org.openjdk.jol.vm.VM;
public class Array {
public static void main(String [] args){
int [] array = new int[3];
System.out.println(ClassLayout.parseInstance(array).toPrintable());
}
}

我用Java 13:运行这个

java -Djdk.attach.allowAttachSelf -Djol.tryWithSudo=true -cp jol-cli.jar  Array.java

我得到输出:

[I object internals:
OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8     4        (object header)                           18 0e 07 00 (00011000 00001110 00000111 00000000) (462360)
12     4        (object header)                           03 00 00 00 (00000011 00000000 00000000 00000000) (3)
16    12    int [I.<elements>                             N/A
28     4        (loss due to the next object alignment)
Instance size: 32 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

这是非常明显的:

12 bytes --> Object headers
4  bytes --> size of array
12 bytes --> elements of array themselves
4  bytes --> padding to align by 8 bytes
----
32 bytes total

使用Java15运行此示例会产生相同的输出,即相同的32 bytes。应为。。。


对于第二部分,我想禁用JVM优化:-XX:-UseCompressedOops。我用Java 13:运行这个

java -Djdk.attach.allowAttachSelf -Djol.tryWithSudo=true -cp jol-cli.jar -XX:-UseCompressedOops  Array.java

[I object internals:
OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
0     4        (object header)                           11 00 00 00 (00010001 00000000 00000000 00000000) (17)
4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8     4        (object header)                           40 0c f0 33 (01000000 00001100 11110000 00110011) (871369792)
12     4        (object header)                           02 00 00 00 (00000010 00000000 00000000 00000000) (2)
16     4        (object header)                           03 00 00 00 (00000011 00000000 00000000 00000000) (3)
20     4        (alignment/padding gap)
24    12    int [I.<elements>                             N/A
36     4        (loss due to the next object alignment)
Instance size: 40 bytes
Space losses: 4 bytes internal + 4 bytes external = 8 bytes total

嗯,也有点意料之中:

16 bytes --> object headers (I did -XX:-UseCompressedOops after all)
4 bytes  --> array size
4 bytes  --> alignment for array headers (AFAIK this is only done for arrays)
12 bytes --> array elements themselves
4 bytes  --> 4 bytes padding
----
40 bytes total

现在让我们用Java15:运行相同的示例

[I object internals:
OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8     4        (object header)                           0e 09 00 00 (00001110 00001001 00000000 00000000) (2318)
12     4        (object header)                           03 00 00 00 (00000011 00000000 00000000 00000000) (3)
16    12    int [I.<elements>                             N/A
28     4        (loss due to the next object alignment)
Instance size: 32 bytes

为什么现在是32 bytes?为什么不使用40,就像使用Java 13一样?

在Java 13和Java 15中,这两个选项默认都处于启用状态:

java -XX:+PrintFlagsFinal -version | grep Compressed
bool UseCompressedClassPointers  = true                                 
bool UseCompressedOops           = true

-XX:-UseCompressedOops被禁用时,意味着UseCompressedClassPointers也被禁用。这就是为什么当UseCompressedOops关闭时,报头大小增加4 bytes,因为UseCompressedOops关闭UseCompressedClassPointers。至少Java 13中是这样的:

java -XX:+PrintFlagsFinal -XX:-UseCompressedOops -version | grep Compressed
bool UseCompressedClassPointers = false                                  
bool UseCompressedOops          = false

Java 15中的情况发生了变化:

bool UseCompressedClassPointers = true                                 
bool UseCompressedOops          = false

所以禁用UseCompressedOops并不意味着UseCompressedClassPointers也被禁用,所以它停留在4 bytes

不过,我自己回答了这个问题,如果有人找到相关的错误/更改就好了吗?到目前为止,我还没有在这方面取得成功。

相关内容

  • 没有找到相关文章

最新更新