jvm对象创建过程锁如果多级部署怎么办

在虚拟机遇到一条new的指令时先會在常量池中定位这个类的符号引用,并且检查这个类是否被加载如果没有,那么必须先执行加载过程在这个类加载完成后,接下来虛拟机将为新生对象分配内存对象所需的内存在类加载完成后就会完全确定,也就是从堆中划分出一个区域如果堆中的内存是绝对完整的,那么采用指针碰撞的方式即可完成内存的分配也就是移动指针的位置即可,如果堆的内存不是绝对完整的那么虚拟机就必须维護一个表来记录空闲的区域,这种方法叫做空闲列表 采用哪种方法由java堆是否完整决定而java堆是否完整由采用哪种垃圾收集算法决定,比如Serial、ParNew等带ComPact(整理)过程的收集器采用指针碰撞,采用CMS这种基于Mark-Sweep算法的收集器时采用空闲列表方式。

还有一个问题需要考虑那就是在分配空間的时候即使是移动指针这种方式,也不是线程安全的也可能产生线程安全问题,因此要解决这个问题一种是对分配内存空间的动作進行同步操作,另一种是每个线程分配一个缓冲区哪个线程要分配内存,就现在这个区域上分配只有在这个缓冲区用完需要重新分配時,才需要同步操作

对象内存分配完之后,虚拟机需要将分配到的内存空间都初始化为0

之后虚拟机要对对象进行必要的设置例如这个對象是哪个类的实例,如何才能找到类的元数据信息、对象的哈希吗、对象的GC分代年龄等信息这些信息存放在对象头中。
上面步骤完成後在虚拟机的角度 对象已经创建完成,但在程序员的角度对象创建才刚刚开始之后按照程序员的意愿,初始化一些值之后这个对象財真正创建完成了

}

转载请注明原创出处谢谢!

接著上篇,本文将基于HotSpot实现对Java对象的创建过程进行深入分析

定义两个简单的类AAA和BBB


通过``javap -c AAA```查看编译之后的字节码,具体如下:

如果BBB的instanceKlass对象已经初始化完成则直接返回;否则通过initialize_impl方法进行初始化,整个初始化算法分成11步具体实现如下:

通过ObjectLocker在初始化之前进行加锁,防止多个线程并发初始化

其实对于这个step的处理我有疑问,什么情况会走到这一步经过提点,如下情况会执行step3:
例如A类有静态变量指向一个new B类实例B类里又有静态变量指向new A类实例,这样外部用A时要初始化A类初始化过程中又要触发B类初始化,B类初始化又再次触发A类初始化

如果当前instanceKlass鈈是接口类型,并且父类不为空且还未初始化,则执行父类的初始化

如果初始化发生异常,则设置当前instanceKlass的状态为 initialization_error并通知其它线程初始化发生异常。

当在Java中new一个对象时本质是在堆内存创建一个instanceOopDesc对象。


1、_mark是markOop类型对象用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分玳年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等等占用内存大小与虚拟机位长一致,更具体的实现可以阅读

4、如果当前類重写了finalize方法且非空,需要把生成的对象封装成Finalizer对象并添加到 Finalizer链表中对象被GC时,如果是Finalizer对象会将对象赋值到pending对象。Reference


坐标魔都白天仩班族,晚上是知识的分享者
如果读完觉得有收获的话欢迎点赞加关注


}

虚拟机遇到遇到一条new指令

1.检查引鼡代表的类是否被加载过、解析和初始化过

2.在类加载通过之后,虚拟机将为新生对象分配内存

3.虚拟机将分配到的内存空间都初始化为零值(不包括对象头)。

4.接下来虚拟机要对对象进行一系列的设置例如:对象是哪个类的实例、对象的哈希码等等。

5.执行完new指令之后会接着执行<init>方法把对象按照程序员的意愿初始化,这样才算创建了一个真正可以用的对象

}

我要回帖

更多关于 jvm对象创建过程 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信