JVM复习之路(二)——new的过程

创建对象的过程,相信很多人都不陌生,这个操作无关你是新手还是老手,学过java的,基本都是懂得简简单单的使用new,创建一个类的对象

我以前也觉得,一个小小的new,不是每个人都会吗?在我深入学习了JVM之后,我发现,我以前的小小的一个new,在JVM里就是一个很复杂的过程

例如,我要创建一个学生对象,我或许会很简单的写到

Student student = new Student();

在这个过程中,JVM到底发生了什么复杂而有趣的事情呢?我来告诉你

首先,JVM会现在常量池搜索这个类是否已经存在其符号引用,检查Student类是否被加载,解析和初始化过,如果没有,则先开始类加载

随后,JVM会帮此对象分配内存,这个时候,要分为两种情况讨论

1.若堆内存绝对规整,即可用的内存空间和不可用的内存空间分成两块,中间只是用指针来作为分界线,这种情况下,指针向可用内存这边移动相应大小的内存进行分配,此过程称为指针碰撞(Bump the Pointer)以下称为BTP

2.若堆内存并非绝对规整,即可用和不可用的内存零零碎碎地存在,形成一些内存块,此时,需要一张表来维护,称为空闲列表(Free List),用以记录每个内存块是否可用,可用空间有多大,在此表中寻找可用的,且内存足够分配的内存块划分内存

对内存是否规整,取决于使用的GC是否用到压缩整理算法,若是Serial,ParNew等带有Compact过程的则使用BTP分配空间,像CMS这些基于Mark-Sweep的则使用空闲列表

在分配内存的时候,存在并发问题,并非线程安全

解决方案:

1.分配内存动作采取同步,用CAS配上失败重试来保证操作的原子性

2.用本地线程缓冲(Thread Local Allocation Buffer)以下简称TLAB,线程在自己的TLAB上分配内存,当TLAB用完需分配内存时,采用同步的形式分配TLAB空间

JVM是否启用TLAB需要用参数-XX:+/-UseTLAB决定

内存分配完后,JVM令已分配的内存空间初始化为零值,此操作使得对象不赋予初始值也能使用

接下来,JVM往对象头里面存入各种信息(属于哪个类的实例,哈希值,元数据信息,GC分代年龄等信息)

至此,对于JVM而言,对象已被创建,之后就按照程序员的意愿进行初始化,调用<init>方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值