深入理解JVM (1) --- JVM中对象的创建
作者:互联网
在此JVM 主要分析的是Hotspot
- 收到new 指令,去检查这个指令的参数是否能在
常量池
中定位到一个类的符号引用。并检查这个类是否已经被加载、解析、初始化过。如果没有则执行类加载过程。 - 类加载通过后,JVM为新生对象分配内存。(类加载完成后可以确定对象所需的内存大小)方式有:
指针碰撞
、空闲列表
。
指针碰撞:一个指针在空闲内存和使用的内存中间,分配内存的是指针向空闲空间移动对象大小对应的空间。 Serial、ParNew 等带Compact 过程的收集器时,系统采用的分配算法是指针碰撞。
空闲列表:虚拟机维护一个列表,记录哪些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象,并更新表上记录。 使用 CMS 这种基于Mark-Sweep算法的收集器时,通常采用空闲列表。
- JVM 采用CAS + 失败重试的方式保证更新操作的原子性,还有就是通过
TLAB
保证。
TLAB : 将内存分配的动作按照线程化划分在不同的空间中进行,即每个线程在JAVA堆中预先分配一小块内存,称为本地线程分配缓冲(Thread Local Allocation Buffer)。哪个线程要分配内存,就在那个线程的TLAB分配,只有TLAB 用完并分配新的TLAB时,才需要同步锁定。虚拟机是否使用TLAB,可以通过-XX:+/-UseTLAB 参数来设定。
- 内存分配完成后,虚拟机需要将分配到的内存空间都是初始化为零值(不包括对象头),如果使用TLAB,这一工作过程可以提前至TLAB分配时进行。(保证了对象的实例字段在java代码中可以不赋初始值就可以直接使用,程序嫩嫩那个访问到这些字段数据类型所对应的零值。
- JVM对对象进行必要的设置,例如这个对象是哪个类的实例、如何才能找到该类的愿你数据信息、对象的哈希码、对象GC分代年龄等信息。这些信息存放在对象的对象头(Object Header)之中。
- 以上完成,在虚拟机角度已经创建了对象。但是再JAVA 程序角度刚刚开始,Java 程序执行对象
方法。
标签:对象,创建,虚拟机,---,线程,TLAB,JVM,分配 来源: https://www.cnblogs.com/winstonehome/p/14263243.html