java对象在内存中的内存布局

105 阅读2分钟

最终的对象大小必须被8整除,不能被8整除的需要进行填充
java默认是有开启压缩,每个引用占用4字节。没有开启压缩每个引用占用8字节,开启压缩没有引用占4个字节

内存布局

  • mark world 4字节(保存GC,锁、hashcode等内容)
  • 类型指针 4字节
  • 实例数据 看成员变量是什么类型有多少个,比如Integer占用4个字节
  • 对齐填充 填充到可以被8整除

image.png

引入依赖包

<dependency>
    <groupId>org.openjdk.jol</groupId>
    <artifactId>jol-core</artifactId>
    <version>0.9</version>
</dependency>

例子一

在内存中占用16个字节=》16字节=8字节的mark world+4字节类型指针+4字节填充

private  static  class  T{
    
}

public static void main(String[] args) {
    T t=new T();
    
}

image.png

例子二

在内存中占用16个字节=》16字节=8字节的mark world+4字节类型指针+4字节实例数据

private  static  class  T{
   private Integer  a;//4节点 
}

public static void main(String[] args) {
   T t=new T();

}

image.png

例子三

在内存中占用24个字节=》24字节=8字节的mark world+4字节类型指针+12字节实例数据

private  static  class  T{
   private Integer  a;//4节点
   private  long b;// 8字节
}

public static void main(String[] args) {
   T t=new T();

}

image.png

例子四

在内存中占用32个字节=》32字节=8字节的mark world+4字节类型指针+13字节实例数据+7字节填充

private  static  class  T{
    private Integer  a;//4节点
    private  long b;// 8字节
    private boolean  c;//1字节 
}

public static void main(String[] args) {
    T t=new T();
    System.out.println(ClassLayout.parseInstance(t).toPrintable());


}

image.png

例子五

在内存中占用32个字节=》32字节=8字节的mark world+4字节类型指针+17字节实例数据+3字节填充

private  static  class  T{
    private Integer  a;//4节点
    private  long b;// 4字节
    private boolean  c;
    private  String d="fdkfhkdfldk";//4字节压缩引用
}

public static void main(String[] args) {
    T t=new T();
    System.out.println(ClassLayout.parseInstance(t).toPrintable());


}

image.png