JVM总结-对象

对象的建立

首先JVM遇到new指令,会检查指令参数可否在常量池中定位到一个符号引用。而且检查这个符号引用所表明的类是否已被加载、解析和初始化过。若是没有会进行相应的类加载过程。布局

类加载验证经过后,为新生对象分配内存。spa

内存分配完成后,JVM须要将分配到的内存空间都初始化为零。这一步操做保证了对象的实例字段在Java代码中能够不赋初始值就直接使用。线程

对对象进行必要的设置,例如这个对象是哪一个类的实例,如何才能找到类的元数据信息,对象的Hash码值,对象的GC分代年龄等信息。这些信息都放在对象头中,grn指针

上述工做完成后,对虚拟机而言一个新的对象已经产生。从Java程序而言对象的建立刚刚开始。根据当前虚拟机运行状态的不一样,如是否启用偏向锁等,对象头都会有不一样的设置。对象

对象的内存布局:

在HotSpot中,对象在内存中的布局分为3块区域:继承

  • 对象头:

        包含两部分数据:内存

        用于存储对象自身运行时数据,如Hash码、GC分带年龄、锁状态标志、线程持有的锁等源码

        另一部分是类型指针,即对象指向它的类元数据指针,经过这个指针肯定对象是哪一个类的实例。(并非全部的虚拟机都在对象数据上保留类型指针)虚拟机

        

  • 实例数据:

        是对象真正存储的有效信息,也就是程序代码中所定义的各类类型的字段内容。不管父类继承仍是子类定义都要记录,这部分数据受虚拟机分配策略参数和Java在源码中的定义顺序影响。内存管理

  • 对象填充:

    仅仅起着占位符的做用,并非必要的,也无心义。(例如Hot Spot自动内存管理系统要求对象起始地址必须是8字节的证书倍,须要对齐填充来补全)

对象的访问定位

Java程序须要经过栈上的reference数据来访问堆中的具体对象,reference类型在JVM中只规定了一个指向对象的引用,并无定义这个引用经过何种方式去定位,访问堆中对象的具体位置。对象的访问方式取决于JVM的实现方式。

主流方式:

使用句柄

Java堆会划分一块内存做为句柄池,reference中存储的是句柄地址,而句柄中包含了对象的实例数据和类型数据的具体地址信息。

直接访问

reference存储的直接就是对象地址。

优缺点:

使用句柄最大的好处是reference中存储的是稳定的句柄地址,在对象被移动时只改变du句柄中的实例数据指针,而reference不须要修改。

使用直接地址最大的好处是速度更快,节省了一次指针的定位开销。

相关文章
相关标签/搜索