JVM八股第一遍的结尾,感觉对垃圾回收器理解的还是有些迷迷糊糊,复习八股有经验的uu欢迎留言传授经验~
垃圾回收算法
HotSpot为什么要分为新生代和老年代?(根据以下对分代收集算法的介绍回答)
标记-清除算法
首先标记出所有不需要回收的对象,在标记完成之后统一回收没有被标记的对象(通过给这个对象一个标记位)。
不足:
· 标记和清除的过程都不高
· 标记清除后会产生大量不连续的内存碎片
复制算法
解决了标记清除算法的效率和内存碎片问题。复制算法将内存分为大小相同的两块,每次使用其中的一块,当这块内存使用完之后,就将存活的对象复制到另外一块,然后把使用的那块清除掉(也就是每次都对内存的一般进行内存回收)。
不足:
· 可用内存变小
· 不适合老年代(如果存活对象数量比较大,复制性能就会好差)
标记-整理算法
标记过程和“标记-清除”算法一样,但是后续步骤是对所有存活对象进行整理,将其向一端移动,然后清除边界以外的内存
不足:
· 需要整理,效率也不高
分代收集算法
根据对象的存活周期将内存分为两块:新生代,老年代。在新生代中,因为有大量的对象对死去,所以选择复制算法只需付出少量的复制成本即可。而老年代存活几率比较高,选择“标记清除”“标记整理”算法会更好
简述对象的内存布局
对象在堆内存中的存储布局可分为对象头 实例数据 还有对齐填充
对象头主要有:MarkWork(用来存储哈希码,GC分代年龄,锁标志位等信息),类型指针(对象指向他的类元数据指针)
实力数据存储各种类型的字段信息
对齐填充起占位作用,HotSpot虚拟机要求对象的起始地址必须是8的整数倍,所以需要对齐填充。
常见垃圾回收器
新生代收集器:
1)Serial 收集器
Serial收集器用于新生代的单线程收集器,采用复制算法,在它进行垃圾收集时所有用户线程必须暂停。
2)ParNew收集器
ParNew是Serial的多线程版本。ParNew 收集器以多线程,采用复制算法进行垃圾收集工作,收集完之后,用户线程继续开始执行。
3)Parallel Scavenge收集器
是一款用于新生代的多线程收集器,与ParNew的不同之处就是ParNew的目标是尽可能缩短垃圾收集时用户线程的停顿时间,Parallel Scavenge的目标是达到了一个可控制的吞吐量
老年代收集器:
1)Serial Old 收集器
是Serial的老年代版本,采用标记-整理算法。
2)CMS收集器
是一种以最短回收停顿时间为目标的收集器。垃圾收集线程和用户线程同时工作。采用标记清除算法,分为四个步骤:
· 初始标记:暂停其他线程, 标记一下GC Roots能直接关联到的对象
· 并发标记:查找执行并发阶段从年轻代晋升到老年代的对象,进行GC Roots Tracing,标记出全部的垃圾对象
· 重新标记:修正并发标记阶段引用户程序继续运行而导致变化的对象的标记记录。
· 并发清除:用标记-清楚算法清楚垃圾对象
3)Parallel OLd
是Parallel Scavenge的老年代版本,充分利用了多核CPU的计算能力
新生代老年代垃圾收集器
1)G1收集器
该收集器把堆划分为多个大小相等的独立区域,新生代和老年代不再物理隔离。引入Region的概念,从而将原来的一整块内存空间划分为多个小空间,使得小空间可以单独进行垃圾回收
初始标记: 标记与GC Roots直接关联的对象
并发标记: 可达性分析