乘着年轻,多学习 接着上篇《JVM源码分析之Java类加载过程》,本文将基于HotSpot实现对Java对象的创建过程进行深入分析。 定义两个简单的类AAA和BBB 通过``javap -c AAA```查看编译之后的字节码,具体如下: Java中的new关键字对应jvm中的new指令,定义在InterpreterRuntime类中,实现如下: new指令的实现过程: 如果常量池中指定位置(#2)的数据已经是个oop类型,说明BBB的class已经被加载并解析过,则直接通过 如果BBB的instanceKlass对象已经初始化完成,则直接返回;否则通过 step1通过ObjectLocker在初始化之前进行加锁,防止多个线程并发初始化。 step2如果当前instanceKlass处于being_initialized状态,且正在被其它线程初始化,则执行 step3如果当前instanceKlass处于being_initialized状态,且被当前线程初始化,则直接返回。 step4如果当前instanceKlass处于fully_initialized状态,说明已经初始化完成,则直接返回; step5如果当前instanceKlass处于initialization_error状态,说明初始化失败了,抛出异常。 step6设置当前instanceKlass的状态为 being_initialized;设置初始化线程为当前线程。 如果当前instanceKlass不是接口类型,并且父类不为空,且还未初始化,则执行父类的初始化。 step8通过
step9如果初始化过程没有异常,说明instanceKlass对象已经初始完成,则设置当前instanceKlass的状态为 fully_initialized,最后通知其它线程初始化已经完成;否则执行step10 and 11。 step10 and 11如果初始化发生异常,则设置当前instanceKlass的状态为 initialization_error,并通知其它线程初始化发生异常。 5、如果instanceKlass初始化完成, instanceOopDesc当在Java中new一个对象时,本质是在堆内存创建一个instanceOopDesc对象。 instanceOopDesc在实现上继承自oopDesc,其中oopDesc定义如下: 当然,这只是 oopDesc的部分实现,oopDesc包含两个数据成员:_mark 和 _metadata。 instanceOopDesc对象的创建过程instanceOopDesc对象通过 4、如果当前类重写了finalize方法,且非空,需要把生成的对象封装成Finalizer对象并添加到 Finalizer链表中,对象被GC时,如果是Finalizer对象,会将对象赋值到pending对象。Reference Handler线程会将pending对象push到queue中,Finalizer线程poll到对象,先删除掉Finalizer链表中对应的对象,然后再执行对象的finalize方法; 我是占小狼 |
|