Java 创建对象

1.创建对象

1.去常量池中找对于类的符号引用--->检查类是否被加载,解析,初始化过
2.进行类加载
3.加载完之后进行对象堆内存分配(大小在类加载完之后就已知),分配根据内存是否规整,分为指针碰撞(就是一个分界线)和空闲列表,规整由 GC 收集器是否压缩决定,Serial,ParNew 是指针碰撞,CMS 为空闲列表
4.处理对象分配时多线程的对象指针,CAS + 重试还有 TLAB (本地线程分配缓冲)保证每个线程在自己的 TLAB 分配对象
5.对对象分配的区域进行初始化零值,一些默认类型的值
6.设置对象头,包含类的 metadata,对象 GC 分代年龄等
7.执行对象的 init 方法

2.对象内存布局

包含三部分: 对象头,对象实例数据,对齐填充

2.1 对象头

  • 第一部分:运行时数据
内容 状态
对象哈希,分代年龄 未锁定
指向锁记录的指针 轻量级锁定
指向重量锁指针 锁膨胀(重量锁锁定)
GC 标记
偏向线程 ID,时间戳,对象分代年龄 可偏向锁
  • 第二部分:类型指针

对象指向类 metadata 的指针,通过此指针确定对象属于哪一个类实例

2.2 存储对象的内容

包括每个字段的内容,基本类型,oops( ordinary object pointers)

2.3 填充部分

HotSpot VM 内存管理系统要求对象起始地址都是 8 byte 的整数倍。

3.对象访问

java 栈中本地变量表存储一个 reference,通过 reference 来访问对象

  • 句柄

堆内维护一个句柄池,reference 指向对象句柄地址,句柄内容如下:

句柄内容 指向位置
到对象实例的数据的指针 堆中实例池中的对象实例数据
到对象类型数据的指针 方法区中对象类型数据
  • 直接指针

reference 直接指向堆中对象地址,java堆中对象布局包含了类型数据的指针便于访问方法区对象类型数据
HotSpot VM 采用直接指针方式,速度快减少了指针定位。


You'll only receive email when qingliu publishes a new post

More from qingliu