- HotSpot虚拟机在Java堆中对象分配、布局和访问的过程
-
对象的创建
在虚拟机中,通过new指令来表明要创建对象,具体过程为:-
首先检查这个指令的参数是否能在常量池中定位到一个类的符号引用。如果有,则检查这个符号代表的类是否已经被加载、解析和初始化过,否则,先执行相应的类加载过程。
-
类加载检查通过后,为新生对象分配内存。分配方式有两种:
指针碰撞:堆中内存是规整的
空闲列表:堆中内存不规整
除如何划分可用空间外,另一个问题就是如何保证分配内存在并发下是线程安全的:
对分配内存空间的动作进行同步处理
每个线程在Java堆中预先分配一小块内存(TLAB),哪个线程要分配内存,就在哪个线程的TLAB上分配。 -
内存分配完成后,将内存空间初始化为0
-
对对象进行必要的设置,如是哪个对象的实例、对象的哈希码、对象的GC分代年龄等信息。
-
执行init方法,对象创建完成。
-
-
对象的内存布局 :包括对象头、实例数据和对齐填充
- 对象头包含两部分信息:
第一部分用于存储对象自身的运行时数据,如哈希码、GC分代年龄等
第二部分是类型指针,虚拟机通过这个指针来确定这个对象是哪个类的实例 - 实例数据:对象真正存储的有效信息,也是在程序中定义的各种类型的字段内容。
- 填充数据:占位符作用。
- 对象头包含两部分信息:
-
对象的访问定位:句柄和指针