JVM对象创建过程

1 类加载检查
  • jvm通过new指令开始创建对象
  • jvm执行new指令时,首先通过指令参数从常量池中取到需要创建的类名
  • 检查该类是否被加载,解析,和初始化过
  • 如果没有,则执行类的加载过程
  • new指令对应到java语言具体的操作为
    • new 关键字创建对象
    • 对象克隆
    • 对象序列化
2 分配内存

在类加载过后,接下来需要jvm为对象分配内存,有四个问题需要确定

  • 从哪里划分内存?
  • 分配多大的内存?
  • 如何划分内存?
  • 划分内存并发问题如何解决?

从哪里分配内存?

  • 一般直接在新生代伊甸区分配内存
  • 如果伊甸区无法所剩区域不足存放该对象,并且满足大对象的设置,则在老年待分配内存
  • 如果通过逃逸分析满足栈上分配的要求,则直接在虚拟机栈内分配内存

分配多大的内存?

在类加载完成后,类有多少个属性以及每个属性什么类型的数据已经确认,便可以计算出对象所需的内存。

如何划分内存?

  • 划分内存通常有两种方式,指针碰撞和空闲列表
  • 指针碰撞:堆中内存绝对规整,所有使用的内存放在一边,空闲的内存放在另一边,有一个指针指向分界线,那分配内存的方式就仅仅是将该指向分界线的指针移动与对象大小相等的距离。
  • 空闲列表:堆中的内存不是规整的,已使用的内存和空闲的内存相互交错,那么就需要额外开辟出一块内存,记录哪些内存块是可用的,在分配的时候从列表中找出足够大的空间划分给对象

如何解决内存分配时的并发问题?

  • CAS:采用CAS+失败重试机制保证更新操作的原子性,来对分配内存空间的动作进行同步处理;
  • TLAB:Thread Local Allocation Buffer,提前给每个线程划分自己的私有空间(也是从伊甸区分配),通过参数-XX:+UseTLAB来开启(默认开启),-XX:TLABSize指定预分配空间大小
3 初始化
  • 内存分配完成后,由于分配的内存可能是被使用过的;
  • 在jvm垃圾回收阶段,只是标记了非垃圾对象,从而确定哪些内存可以释放使用;
  • 在使用时,需要将分配到的内存空间都初始为零值;
  • 如果使用的TLAB分配的空间,这一过程可以提前至分配TLAB内存时
4 设置对象头
  • 在初始化后,jvm需要对对象头信息进行设置
  • Klass Pointer指针设置
  • Mark Work初始化
5 执行init()方法

执行init()方法,即执行构造方法,在编译阶段,jvm为每一个构造方法生成其对应的init()方法

相关推荐
SL_staff3 分钟前
制造订单交付闭环实践:用跨部门计划模板解决缺料-停机-返工三角死循环
java·开源·产品
device_Any6 分钟前
接口文档写着三个字段,接口返回了五个
android·java·linux
Wang's Blog12 分钟前
Java 项目实战: 交友项目 - 小视频模块实战:访客记录、FastDFS 存储与 SpringCache 缓存
java·缓存·交友
香蕉大香蕉(06敬畏市场)22 分钟前
MySQL 单点详解(09)
java·数据库·mysql·面试·八股·大厂实习
吹什么轩1 小时前
constexpr 完全指南:从 const 的两种含义,到编译期计算的四次演进
java·前端·javascript
她的男孩1 小时前
租户 A 的验证码,却用了租户 B 的 AccessKey:Forge Admin 修跨租户短信串发
java·spring boot·saas
LabVIEW开发1 小时前
LabVIEW 局部变量与数据流:这道 CLAD 题为什么答案是 Undefined
java·开发语言·labview
文丑颜不良啊1 小时前
LeetCode1721~1740题目解析
java·leetcode
wangbing11251 小时前
监控网页项目常用英文缩写
java
麻瓜code1 小时前
双写一致性:为什么是“删缓存“,而不是“改缓存“
java·缓存·mybatis