JVM对象的创建

1.检测所在类是否已经被加载:如未加载先加载类
2.内存分配
对象的大小是在类加载时就已经确定的,所以对象的内存分配只是在内存中分配一个指定大小的空间,一般有两种方式:
分配方式
①指针碰撞:内存中使用的区域较为规整,使用区和空闲区之间由一个指针分割,当需要放入新的数据时,只需要将指针向空闲区域这边移动一段(默认采用)
②空闲列表:内存中剩余空间比较杂乱,这时是由一块区域存储目前空闲空间的索引,当新的数据进来时,先查询空闲列表,然后将数据放入空闲区域
这两种分配方式都存在并发问题,解决方法有两种
a.CAS+失败重试:使用版本号机制,内存分配失败的重新分配直到分配完成
b.本地缓存:在堆中划分出一块专门的针对某类对象的区域,当该类创建对象时优先分配到该区域,内存不足时再按照之前的分配方式。
分配位置
新创建的对象一般分配在堆中,为了防止大量垃圾对象导致频繁的GC,临时对象也可以存在栈中,使用完毕后随栈帧的弹出而销毁,会通过对象逃逸分析和标量替换判断对象是否可以存在栈中。
对象逃逸分析:一个对象如果不会被方法外的数据所使用,属于无法逃逸的对象(即仅在方法内使用的对象),如果对象大小合适,将被存在栈中。
标量替换:标量是指无法分割的量,java中的基本类型变量都属于标量,与之相对应的就是聚合量,对象属于聚合量。标量替换是指可以存储在栈中的对象过大,可以选择将对象拆分成标量存储在栈中,支持方法对对象的使用,而不是真的去创建一个对象。
3.初始化:内存分配完成后,jvm会将分配到的内存空间都初始化零值(不包括对象头),这一操作保证对象的实例字段在代码中可以不赋初始值直接被使用
4.设置对象头
对象由对象头+实例数据+对齐填充组成。
对象头由Mark Word+KlassPointer+数组组成。
1.MarkWord标记字段:在32位中占4位,64位中占8位,存储自身运行时数据,包括哈希值,GC分代年龄,锁状态标志,线程持有锁,偏向线程ID,偏向时间戳
2.KlassPointer类型指针:开启压缩占4位,关闭压缩占8位,类的元数据的指针
3.数组:占4字节,数组对象专有
5.执行init方法:为属性赋指定值并执行构造方法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值