Java对象创建过程

15 篇文章 7 订阅
1 篇文章 0 订阅

STEP1:类加载检查

虚拟机遇到一条 new 指令的时候,首先去常量池中检查该对象的符号引用,并检查该引用是否被加载过、初始化过、解析过。如果没有,就要去执行类加载过程。

STEP2:分配内存

在类加载检查通过后,接下来虚拟机将为新生对象分配内存。对象所需的内存大小在类加载完成后便可确定。分配方式有两种:”指针碰撞”和“空闲列表”两种,选择那种分配方式由Java 堆是否规整决定,而 Java 堆是否规整又由所采用的垃圾收集是否带有压缩整理功能所决定。

指针碰撞:

适用场合:堆内存规整(没有内存碎片)的情况(复制算法,标记压缩算法)

原理:用过的内存全部整合到一边,其中用一个指针来分隔,来了一个新对象,指针往没有用过内存的地方移动。

GC 收集器:serial(标记压缩),parallel(serial 的多线程版本)

空闲列表

使用场合:堆内存不规整,有内存碎片(标记清楚算法)

原理:虚拟机会维护一个列表,该列表中会记录那些内存块是可用的,在分配的是偶,找一块足够大的内存块来创建对象实例,然后更新列表。

内存分配并发问题

在创建对象中,我们肯定不能允许另外的线程来干扰,就比如你女票被男的骚扰了,你爽吗?所以我们虚拟机在创建对象的时候要保证线程安全。通常也有两种方式来保证创建对象    是线程安全的:

CAS+失败重试:

CAS 是乐观锁的一种实现。乐观锁是指,它每次都假设没有其他线程来干扰的,如果有线程干扰,那就重新创建,直到创建成功。这样可以保证更新操作的原子性。

TLAB:

为每一个线程预先在 Eden 区域分配一块内存,首先 TLAB 分配,对象的需要的内存大于了 TLAB 提供的,再采用 CAS 进行内存分配。

STEP3:初始化零值

当内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值(不包括对象头),这    一步操作保证了对象的实例字段在 Java 代码中可以不赋初值就直接使用,程序能访问到这些字段的数据类型所对应的零值。就跟有些成员变量你赋值了,有些没有赋值,那么那    些没有赋值的就是 Null 的道理是一样的。

STEP4:设置对象头

初始化完成后,我们需要一个东西去辨认我们这个新创建对象的一些信息。很多事物的基本信息都存在什么头,比如 http,它的大概属性都会存在信息头中,比如请求方式之类的。当然我们这个新创建对象也是一样的,我们就用对象头来存储对象是那个类的实例、类的元数据信息、对象的哈希码、对象的 GC 分代年龄等信息。

STEP5:执行 init 方法

经过上面 4 步操作后,我们从虚拟机的角度来看,一个新的对象已经产生了,但从 Java 程序中,对象创建好了,我们都一般还有构造函数去初始化值,所以<init>方法就起作用    了,把对象按照程序员的意愿来进行初始化,这样 5 步才算把一个真正可用的对象完全产生出来。

更多JVM笔记:

https://blog.csdn.net/qq_40262372/article/details/113733631

B站视频讲解如何三个月学习JAVA拿到实习Offer:

https://www.bilibili.com/video/BV1dV411t71K

B站,VX关注:万小猿,我们会不断努力更新更多相关的知识笔记

如果想要在学习的道路上和更多的小伙伴们交流讨论

请加Q群:725936761   

欢迎每一位小伙伴的加入

我们一起朝着目标加油!冲锋陷阵!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

万小猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值