我所提出的只是一个简单的问题。根据Java文档和许多有关Java内存对象布局的文章,如果我们有一个带有一个int
变量的类,则该对象的总内存消耗将为:
public class Ab {
int b;
}
public static void main(String args[]) throws InterruptedException {
Ab ab = new AB();
}
现在的问题是,当我使用Visual vm并查看堆转储以观察这一理论方法时,我注意到该对象的内存消耗为 20 字节而不是 16 ?为什么会这样呢?有人可以向我解释吗?
答案 0 :(得分:5)
使用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)
答案 1 :(得分:1)
根据热点文档中的“对象标头布局”部分: https://wiki.openjdk.java.net/display/HotSpot/CompressedOops
“对象标头包含一个本机大小的标记字,一个克拉斯字,一个32位长的字(如果对象是数组),一个32位间隙(如果对齐规则要求),然后零个或多个实例字段,数组元素或元数据字段。
所以这意味着您的情况看起来像这样: