jvm 内存管理-hotspot虚拟机对象创建

        创建对象通常是new 来完成

        虚拟机收到一条new指令,首先检查该指令的参数能否在常量池定位到一个类的符号引用,并检查符号引用代表的类,是否已被加载,解析,初始化,如没有,先执行相应的类加载过程。

        类加载检查通过后,虚拟机为新生对象分配内存,对象所需内存大小在类加载完成后可完全确定。

         对象分配空间:把一块确定大小的内存从java堆中分出来

  1. 指针碰撞:内存绝对规整,用过的和空闲的内存各放一边,中间放指针作为分界点指示器,分配内存仅是将指针向空闲空间挪动一段与对象大小相等的举例,Serial,ParNew等带Compact过程的收集器时采用指针碰撞
  2. 空闲列表:java堆中内存不是绝对规整的,虚拟机需维护一个列表来记录哪一块内存是可用的,再分配时从列表找一块足够大的空间划分给对象实例,并更新列表记录,CMS基于Mark-Sweep算法的收集器,采用空闲列表。
  3. 对象创建是非常频繁的操作,并发情况下不是线程安全的。
  •  分配内存空间同步处理:虚拟机采用CAS加失败重试,保证更新操作的原子性
  • 内存分配的动作按线程划分不同空间中进行:每个java堆预先分配一小块内存,称为本地线程分配缓冲(TLAB),线程需分配内存,在对应TLAB分配,TLAB用完分配新的TLAB,需同步锁定,虚拟机是否需要使用TLAB,-XX:+-UseTLAB设定   

    初始化零值:内存分配完成后,虚拟机需将分配的内存空间初始化零值(不包括对象头),如果使用TLAB,需要在分配TLAB时进行,这个操作保证对象的实例字段在Java代码不赋初始值访问这些字段数据类型所对应的零值
    虚拟机对对象必要的设置:如对象是哪个类的实例,如何找到类的元数据信息,对象哈希码,对象的GC分代年龄等,这些信息存放在对象的对象头中。
    至此,对虚拟机来说,一个对象已经产生了,而从java程序来看,还需执行init方法,真正可用的对象才算产生,new 指令后是否需要init,由invokespecial指令决定

本文内容主要是学习周志明老师的《深入理解Java虚拟机》一书的学习笔记,仅作学习巩固整理知识点使用,在此感谢周老师。

猜你喜欢

转载自blog.csdn.net/ghostwuxiao/article/details/81065574