声明:本文是个人学习笔记,内容来自《深入理解Java虚拟机·JVM高级特性与最佳实践》周志明 与网络文章
Java虚拟机在执行Java程序的过程中会把它管理的内存划分为若干个不同的数据区域。这些区域都有各自的用途,根据Java虚拟机规范的规定,虚拟机所管理内存会被分为如下图所示的几个区域:

? 虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载、解析和初始化过。如果没有,那必须先执行相应的类加载过程。在类加载检查通过后,接下来虚拟机将为新生对象分配内存。对象所需内存的大小在类加载完成后,便可以完全确定,为对象分配空间的任务等同于把一块确定大小的内存从java堆中划分出来。内存分配完成后,虚拟机将要分配到的内存空间都初始化为零值(不包括对象头),如果使用TLAb,这一工作过程也可以提前至TLAB分配时进行。这一步操作,保证了对象的实例字段在java代码中可以不赋是初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值。最后在执行new指令后,会接着执行init方法,把对象按照程序员的意愿进行初始化,这样一个真正可用的对象才算完全产生出来。
ps:虚拟机是否使用TLAb,可以通过–XX:+/UseTLAB参数来设定

说明:如果使用句柄访问的话,那么Java堆中将会划分出一块儿内存作为句柄池,reference中存储的就是对象的句柄
地址,而句柄中包含了对象实例数据与类型数据各自的具体的地址信息。

说明:如果使用直接指针访问,那么Java堆对象的布局中就必须考虑如何放置访问类型数据的具体信息,而reference中
存储的直接就是对象地址。
使用句柄来访问的最大好处就是reference中存储的是稳定的句柄地址,在对象被移动(垃圾收集时移动对象是非常普遍的行为)时只会改变句柄中的实例数据指针,而reference本身不需要修改;使用直接指针访问方式的最大好处就是速度更快,它节省了一次指针定位的时间开销,由于对象的访问在Java中非常频繁,因此这类开销积少成多后也是一项非常可观的执行成本。
注:就HotSpot而言,它是使用的直接指针的方式进行对象访问的。
原文:https://www.cnblogs.com/xyzshm/p/12537509.html