堆中的对象内存分布


Java 堆中的对象内存

1. java中的对象指向问题

public class HeapMemory {

    private Object obj1 = new Object();

    public static void main(String[] args) {
        Object obj2 = new Object();
    }
}

1.1 方法区指向堆

类的属性存放在 方法区 中,该属性对应的实例存放在堆中。即obj1符号引用在方法区中,指向堆中对象实例内存。

1.2 虚拟机栈指向堆

类的方法中的属性存放在虚拟机栈的 局部变量表 中,对象实例同样存在在堆中。

zhan

2. 堆中的对象实例的布局

2.1 对象内存模型

java 中的对象内存布局:

  1. 对象头 Header
    • mark word : 8 字节。存放对象的hashcode、同步状态、指向同步信息的指针、GC状态位。
    • class pointer : 未指针压缩时 8 字节,压缩后 4 字节
    • 数组 length (数组对象特有): 4 字节
  2. 对象实例数据 Instance Data :存放对象的所有属性字段,按字段类型来分配空间,如int占4字节;
  3. 对齐填充 Padding : 填充为 8 字节的整数倍,目的是为了寻址方便

a

2.2 Object obj = new Object() 占用的字节

实例数据为空,mark word 占 8 字节,其他:

  • 若开启了类指针压缩 则 class pointer 占4字节,然后 padding 填充 4 字节
  • 若没开启,则 class pointer 占 8 字节,padding 不填充

所以,一共占用 16 字节。

3. 堆对象的访问

3.1 句柄访问

堆中划分出一块空间来存放 句柄池 , 即 方法区/栈帧 中的对象引用是存放的句柄地址,通过句柄池再在堆中查找对象的实际地址。

3.2 直接指针访问 (hot spot)

堆中直接存放对象的实例数据,即 方法区/栈帧 中的对象引用直接指向堆实例的地址。


文章作者: Yu Yang
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Yu Yang !
 上一篇
Java 四种引用类型 Java 四种引用类型
四种引用类型1. 强引用强引用就是最普通的引用方式。 GC 时,只要堆中的对象实例存在强引用与之关联,则绝不会被垃圾回收。 Object o = new Object(); 方法中的局部变量的强引用会在方法退出栈帧后自动销毁引用。 对于类的
2020-10-22
下一篇 
JVM 内存结构 JVM 内存结构
JVM内存区域划分JVM运行时数据区分为:堆、方法区、栈(虚拟机栈、本地方法栈)、程序计数器。 1. 程序计数器 Program Counter 线程私有,是当前线程的字节码行号指示器。 如果线程执行 Java 方法,指示字节码指令的地址
2020-09-26
  目录