JVM产生以及引用一个对象

JVM如何产生一个对象?

        程序员视角:new     clone     反序列化  都可以生成一个对象在内存中。(JVM的给我们带来的方便,两个字:伟大)

        JVM视角:(大约需要以下5步骤)

                1. (验证类加载)检查创建对象的指令参数,能否在常量池中定位到一个类符号的引用(Class信息存放在方法区中,常量池也是方法区的一部分)。并且检查这个符号引用代表的类是否已经被加载,初始化。

                2.(为新生对象分配内存)由于一个对象所需内存在类加载完成后便可以确定了(一个对象分为对象头(32位机器32bit、64位机器64bit),实例数据(类中定义的各种类型的字段,包括从父类中继承下来的),对其填充(占位作用,JVM规定对象大小必须是8字节的整数倍)),因此给对象划分内存等同于从堆中直接划分一段内存出来。分配方式:指针碰撞和空闲列表两种方法。

                        2.1在分配内存时,需要考虑线程安全。两个解决方案:a)采用 CAS配上失败重试,保证原子性。

                                 b) 将内存按照线程划分到不同的空间去进行分配,称为本地线程分配缓冲(Thread Local Allocation Buffer)

                3.(将分配到的内存空间初始化为零)不包括对象头。  如果采用TLAB方式,可以提前至TLAB分配时进行这步。

                4.(对新生对象的头信息进行补充,例如对象是哪个类的,hashCode,GC分代年龄等)

                5.(执行初始化方法,这个初始化方法是按照程序员的意愿去处理这个对象的初始化工作)执行构造方法的赋值代码等。

    


JVM如何引用一个对象?(图片来自JVM高级特性第二版)

        1.句柄

            JVM产生以及引用一个对象

        2.直接指针    

            JVM产生以及引用一个对象


    这样两种访问方式的优缺点很明确了:

            有句柄池的速度慢,没有句柄池的怕对象的移动。