不小心,我无意中发现了Java 15中的一个变化,而我并没有意识到这一点。假设我有一个非常简单的问题:由3个整数组成的数组的大小是多少?为此,我使用约尔。代码相当琐碎:
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使用Java 15运行此示例会产生相同的输出,相同的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现在,让我们使用Java 15运行相同的示例:
[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,就像Java13那样?
发布于 2020-07-13 15:29:22
在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 = falseJava 15中的情况发生了变化:
bool UseCompressedClassPointers = true
bool UseCompressedOops = false因此,禁用UseCompressedOops并不意味着UseCompressedClassPointers也被禁用,因此它停留在4 bytes。
虽然,我自己回答了这个问题,但是如果有人发现了相关的错误/更改,那就太好了。到目前为止,我还没有在这方面取得成功。
https://stackoverflow.com/questions/62879157
复制相似问题