Java普通对象内存布局

一个普通对象,在内存中占多大?

普通对象在内存中主要分三部分组成

  1. 对象头:对象头分markwork和classpointer组成,markword主要存放标记位,classpointer用来存放类型指针
  2. 对象数据:这里主要存放的是指针的地址
  3. 对齐填充:hotspot规定,对象的起始地址占用内存大小必须为8的整倍数,不足的话,要补齐

Java普通对象内存布局

这个内存占用大小还跟机器的位数(32或64位)、是否开启指针压缩(-XX:-UseCompressedOops)有关,下面举例:

  1. 引入jar包

JOL,全称Java Object Layout,Java对象布局

<dependency>
    <groupId>org.openjdk.jol</groupId>
    <artifactId>jol-core</artifactId>
    <version>0.16</version>
</dependency>
  1. 测试代码(开启指针压缩)
public static class TTT {
    
}

public static void main(String[] args) {
    TTT ttt = new TTT();
    String str = ClassLayout.parseInstance(ttt).toPrintable();
    System.out.println(str);
}

测试结果:

OFF  SZ               TYPE DESCRIPTION               VALUE
  0   8                    (object header: mark)     0x0000000000000001 (non-biasable; age: 0)
  8   4                    (object header: class)    0xf800c147
 12   4   java.lang.String TTT.a                     null
Instance size: 16 bytes

mark:占用了8个字节,class指针占用了4个,String实例指针占用了4个,没有对齐,一共占用了16个字节

  1. 测试代码(关闭指针压缩)
OFF  SZ               TYPE DESCRIPTION               VALUE
  0   8                    (object header: mark)     0x0000000000000001 (non-biasable; age: 0)
  8   8                    (object header: class)    0x00000001260650e0
 16   8   java.lang.String TTT.a                     null
Instance size: 24 bytes

mark:占用了8个,class指针占用了8个,String实例指针占用了8个,没有对齐,一共24个字节

  1. 总结:

32位不可以开启指针压缩,64位的才可以开启指针压缩,class pointer开启指针压缩占用4个字节,不开启,则占用8个字节,在64位系统中,默认是开启指针压缩的。
问:new Object() 占用了多大内存?
答:16个字节(开不开启指针压缩都一样)
问:对象头都包含什么?mark word里都记录了什么信息?
答:对象头包含了mark word和class pointer,mark word里记录了对象锁的信息,hashcode以及GC信息

posted @ 2022-05-09 16:33  在谷歌上百度  阅读(52)  评论(0编辑  收藏  举报