使用VisualVM堆转储计算Java对象的内存使用情况与理论方法不匹配

Mix*_*dis 2 java memory jvm jvm-hotspot

我只带一个简单的问题.根据java文档和许多关于java内存对象布局的文章,如果我们有一个带有一个int变量的类,那么该对象的总内存消耗将是:

  • 标题为8个字节
  • int为4个字节
  • 4字节填充(将总数舍入为8字节的倍数)= 总共16字节
public class Ab {        
    int b;
}
Run Code Online (Sandbox Code Playgroud)

public static void main(String args[]) throws InterruptedException {
    Ab ab = new AB();  
}  
Run Code Online (Sandbox Code Playgroud)

我现在的问题是,当我使用Visual vm并查看堆转储来观察这个理论方法时,我注意到该对象的内存消耗是20字节而不是16字节?为什么会这样?有人可以向我解释一下吗?

Ole*_*hov 5

使用Java对象布局工具,我收到以下输出:

 OFFSET  SIZE   TYPE DESCRIPTION        VALUE
      0    12        (object header)    N/A
     12     4    int Ab.b               N/A

Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
Run Code Online (Sandbox Code Playgroud)

并使用-XX:-UseCompressedOopsVM选项(禁用压缩引用):

 OFFSET  SIZE   TYPE DESCRIPTION                                VALUE
      0    16        (object header)                            N/A
     16     4    int Ab.b                                       N/A
     20     4        (loss due to the next object alignment)

Instance size: 24 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
Run Code Online (Sandbox Code Playgroud)

Java环境:

java version "11" 2018-09-25
Java(TM) SE Runtime Environment 18.9 (build 11+28)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11+28, mixed mode)
Run Code Online (Sandbox Code Playgroud)