Java对象创建过程

Java是一门面向对象语言,Java程序运行过程中无时无刻都有对象被创建出来。

对象创建过程

类加载检

  1. 当Java虚拟机遇到一条字节码new指令时,首先会去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,那么必须先执行相应的类加载过程。(类加载过程?待更新)

分配内存

  1. 在类加载检查通过以后,接下来虚拟机将为新生对象分配内存。对象所需的内存大小在类加载完全之后便可以完全确定(如何确定?待更新),为对象分配空间的任务实际上等同于把一块确定大小的内存块从Java堆中划分出来。分配方式有“指针碰撞”和“空闲列表”。选择那种分配方式有Java堆是否规整决定,而Java堆是否规整又由所采用的垃圾收集器是否带有空间压缩整理(Compact)的能力决定。

除了划分空间之外,还有一个另外需要考虑的问题:对象创建在虚拟机中是非常频繁的行为,即使仅仅修改一个指针所指向的位置,在并发的情况下也并不是线程安全的,可能出现给正在给A对象分配内存,指针还没来得及修改,对象B又同时使用了原来的指针来分配内存的情况。
两种解决方案:

  • CAS+失败重试:
    • 即对分配内存空间的动作进行同步处理;​​​​​​​虚拟机实际上采用的是CAS+失败重试的方式保证更新操作的原子性
    • CAS 是乐观锁的⼀种实现⽅式。所谓乐观锁就是,每次不加锁⽽是假设没有冲突⽽去完成某项操作,如果因为冲突失败就重试,直到成功为⽌。
  • TLAB:把内存分配的动作按照线程划分在不同的空间中进行,即每个线程在Java堆中预先分配一小块内存,称为本地线程分配缓冲(Thread Local Allocation Buffer,TLAB),那个线程要分配内存,就在那个线程的本地缓冲区中分配,只有本地缓冲区用完了,分配新的缓冲区时才需要同步锁定。

初始化零值

  1. 内存分配完成之后,虚拟机必须将分配到的内存空间(不包括对象头)都初始化为零值,如果使用TLAB的话,这项工作也可以提前到TLAB分配时顺便进行。这步操作保证了对象的实例字段在Java代码中可以不赋初始值就直接使用,使程序能访问到这些字段数据类型所对应的零值。

设置对象头

  1. 初始化完成之后,Java虚拟机还要对对象进行必要的设置,例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的 GC 分代年龄等信息。 这些信息存放在对象头中。 另外,根据虚拟机当前运⾏状态的不同,如是否启⽤偏向锁等,对象头会有不同的设置⽅式。(对象头设置过程?待更新)

执⾏ init ⽅法

  1. 在上⾯⼯作都完成之后,从虚拟机的视⻆来看,⼀个新的对象已经产⽣了,但从 Java 程序的视⻆来看,对象创建才刚开始, ⽅法还没有执⾏,所有的字段都还为零。所以⼀般来说,执⾏ new 指令之后会接着执⾏ ⽅法,把对象按照程序员的意愿进⾏初始化,这样⼀个真正可⽤的对象才算完全产⽣出来。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值