首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >jdk-13和jdk-15中的UseCompressedOops UseCompressedClassPointers

jdk-13和jdk-15中的UseCompressedOops UseCompressedClassPointers
EN

Stack Overflow用户
提问于 2020-07-13 15:29:22
回答 1查看 1.1K关注 0票数 6

不小心,我无意中发现了Java 15中的一个变化,而我并没有意识到这一点。假设我有一个非常简单的问题:由3个整数组成的数组的大小是多少?为此,我使用约尔。代码相当琐碎:

代码语言:javascript
复制
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中运行这个程序:

代码语言:javascript
复制
  java -Djdk.attach.allowAttachSelf -Djol.tryWithSudo=true -cp jol-cli.jar  Array.java

我得到了输出:

代码语言:javascript
复制
    [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

这一点很明显:

代码语言:javascript
复制
     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中运行这个程序:

代码语言:javascript
复制
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

嗯,这也是意料之中的:

代码语言:javascript
复制
     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运行相同的示例:

代码语言:javascript
复制
[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那样?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-13 15:29:22

在Java 13和Java 15中,默认情况下这两个选项都是打开的:

代码语言:javascript
复制
java -XX:+PrintFlagsFinal -version | grep Compressed

 bool UseCompressedClassPointers  = true                                 
 bool UseCompressedOops           = true

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

代码语言:javascript
复制
  java -XX:+PrintFlagsFinal -XX:-UseCompressedOops -version | grep Compressed

    bool UseCompressedClassPointers = false                                  
    bool UseCompressedOops          = false

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

代码语言:javascript
复制
    bool UseCompressedClassPointers = true                                 
    bool UseCompressedOops          = false

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

虽然,我自己回答了这个问题,但是如果有人发现了相关的错误/更改,那就太好了。到目前为止,我还没有在这方面取得成功。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62879157

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档