java - 使用 VisualVM 堆转储计算 java 对象的内存使用情况与理论方法不符

标签 java memory jvm jvm-hotspot

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

  • 8字节为标题
  • 4字节为int
  • 4 字节填充(将总数四舍五入为 8 字节的倍数)= 总共 16 字节
public class Ab {        
    int b;
}

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

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

最佳答案

使用 Java Object Layout工具我收到以下输出:

 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

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

 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

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)

关于java - 使用 VisualVM 堆转储计算 java 对象的内存使用情况与理论方法不符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53597952/

相关文章:

java - WebStorm 11 全新安装无法在 Mac OSX 中启动

java - 变量初始化

java - Swing 是否支持 Windows 7 风格的文件选择器?

java - 我们可以调用一个带有 java.lang.reflect.Array 参数的方法吗?

c++ - 在其赋值运算符方法中调用对象的析构函数

java - 我可以对堆转储文件运行 Java 垃圾回收吗?

java - 在 ArrayList 上使用递归

memory - cudamemcpy 错误 :"the launch timed out and was terminated"

c# - WPF内存碎片

java - JVM 是否在系统中存储内存?如果有,如何清除?