Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于+XX:CompactFields,JVM 并没有把子类之中较窄的变量插入到父类变量的空隙之中。 #198

Open
Lx0815 opened this issue Apr 20, 2023 · 0 comments

Comments

@Lx0815
Copy link

Lx0815 commented Apr 20, 2023

环境

Java 环境

java version "1.8.0_351"
Java(TM) SE Runtime Environment (build 1.8.0_351-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.351-b10, mixed mode)

JVM 参数默认值

通过命令 java -XX:+PrintFlagsFinal 查看参数的默认值可以发现 CompactFields 确实默认为 true,但是它似乎没有作用。
image

IDE 环境

IntelliJ IDEA 2023.1 (Ultimate Edition)
Build #IU-231.8109.175, built on March 28, 2023
For educational use only.
Runtime version: 17.0.6+10-b829.5 amd64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
Windows 10.0
GC: G1 Young Generation, G1 Old Generation
Memory: 2016M
Cores: 12
Registry:
debugger.new.tool.window.layout=true
debugger.valueTooltipAutoShowOnSelection=true
ide.experimental.ui=true

Non-Bundled Plugins:
cn.com.pism.batslog (23.03.02.2009-RE)
com.intellij.zh (231.250)
leetcode-editor (8.7)
com.intellij.ideolog (203.0.30.0)
CMD Support (1.0.5)
coderead.IdeaPlugins.maven (1.1)
com.intellij.plugin.adernov.powershell (2.0.10)
MavenRunHelper (4.23.222.2964.0)
com.baomidou.plugin.idea.mybatisx (1.5.5)
cn.yiiguxing.plugin.translate (3.4.2)

Kotlin: 231-1.8.20-IJ8109.175

Windows 环境

Win10 专业版 19045.2728

测试代码

class F2 {
    byte a1;
    boolean a2;
    char a3;
    short a4;
    int a5;
    float a6;
    long a7;
    double a8;

    S2 a9;
}

class S2 extends F2 {
    boolean b1;
}

public class T {

    public static void main(String[] args) {
        f2_s2();
    }

    private static void f2_s2() {
        System.out.println(ClassLayout.parseInstance(new S2()).toPrintable());
        /* 运行结果
        从运行结果来看并没有把小字段添加到间隙中去

        _2._3._2_object_memory_layout.test1.S2 object internals:
        OFF  SZ                                     TYPE DESCRIPTION               VALUE
          0   8                                          (object header: mark)     0x0000000000000001 (non-biasable; age: 0)
          8   8                                          (object header: class)    0x000002b97f14dcc0
         16   8                                     long F2.a7                     0
         24   8                                   double F2.a8                     0.0
         32   4                                      int F2.a5                     0
         36   4                                    float F2.a6                     0.0
         40   2                                     char F2.a3
         42   2                                    short F2.a4                     0
         44   1                                     byte F2.a1                     0
         45   1                                  boolean F2.a2                     false
         46   2                                          (alignment/padding gap)
         48   8   _2._3._2_object_memory_layout.test1.S2 F2.a9                     null
         56   1                                  boolean S2.b1                     false
         57   7                                          (object alignment gap)
        Instance size: 64 bytes
        Space losses: 2 bytes internal + 7 bytes external = 9 bytes total
         */
    }
}

从运行结果可以发现:父类变量在偏移量为 46 的位置出现了一个大小为 2 的间隙,但是 JVM 并没有将子类中大小为 1 的 boolean 变量插入到父类变量的间隙中。如果将子类的 boolean 变量插入到间隙中,这将使整个对象的大小缩减为 56 bytes,并且只浪费 1 bytes,而不是占用 64 bytes 浪费 9 bytes。这是为什么呢?我希望是我这对块知识的理解有误。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant