深入理解JVM (1) --- JVM中对象的创建

在此JVM 主要分析的是Hotspot

  1. 收到new 指令,去检查这个指令的参数是否能在常量池中定位到一个类的符号引用。并检查这个类是否已经被加载、解析、初始化过。如果没有则执行类加载过程。
  2. 类加载通过后,JVM为新生对象分配内存。(类加载完成后可以确定对象所需的内存大小)方式有:指针碰撞空闲列表

指针碰撞:一个指针在空闲内存和使用的内存中间,分配内存的是指针向空闲空间移动对象大小对应的空间。 Serial、ParNew 等带Compact 过程的收集器时,系统采用的分配算法是指针碰撞。
空闲列表:虚拟机维护一个列表,记录哪些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象,并更新表上记录。 使用 CMS 这种基于Mark-Sweep算法的收集器时,通常采用空闲列表。

  1. JVM 采用CAS + 失败重试的方式保证更新操作的原子性,还有就是通过TLAB保证。

TLAB : 将内存分配的动作按照线程化划分在不同的空间中进行,即每个线程在JAVA堆中预先分配一小块内存,称为本地线程分配缓冲(Thread Local Allocation Buffer)。哪个线程要分配内存,就在那个线程的TLAB分配,只有TLAB 用完并分配新的TLAB时,才需要同步锁定。虚拟机是否使用TLAB,可以通过-XX:+/-UseTLAB 参数来设定。

  1. 内存分配完成后,虚拟机需要将分配到的内存空间都是初始化为零值(不包括对象头),如果使用TLAB,这一工作过程可以提前至TLAB分配时进行。(保证了对象的实例字段在java代码中可以不赋初始值就可以直接使用,程序嫩嫩那个访问到这些字段数据类型所对应的零值。
  2. JVM对对象进行必要的设置,例如这个对象是哪个类的实例、如何才能找到该类的愿你数据信息、对象的哈希码、对象GC分代年龄等信息。这些信息存放在对象的对象头(Object Header)之中。
  3. 以上完成,在虚拟机角度已经创建了对象。但是再JAVA 程序角度刚刚开始,Java 程序执行对象 方法。
原文地址:https://www.cnblogs.com/winstonehome/p/14263243.html