一、垃圾回收器概述
(一)分类
1、按线程数分--串行和并行
串行:Serial Collector
并行:Parallel Collector
2、按工作模式分---并发式和独占式
并发式:Concurrent
独占式:STW
3、按是否对空间碎片进行序列化整理---压缩式和非压缩式
4、按工作的内存区间---年轻代和老年代
新生代GC:Serial、ParNew、Parallel Scavenge
老年代GC: Serial Old、Parallel Old、CMS
整堆GC:G1
(二)七种经典GC
1、七种GC分类
- 串行GC:Serial、Serial Old
- 并行GC:ParNew、Parallel Scavenge、Parallel Old
- 并发GC:CMS、G1
2、七种GC的新生代和老生代组合关系
(1)Serial GC+Serial Old GC
(2) ParNew GC+CMS GC+Serial Old GC
(3) Parallel Scavenge GC+Parallel Old GC
(4) G1 GC---既回收新生代又回收老年代
3、七种回收器特点
(1)Serial GC、Serial Old GC--串行回收
- 针对新生代的回收算法,Serial 收集器----采用复制算法
- 老年代对应的串行垃圾回收器是Serial Old收集器----标记-压缩算法
(2)ParNew GC--并行回收
(3)Parallel GC、Parallel Old GC、Parallel Scavenge--吞吐量优先
(4)CMS GC(Concurrent Mark Sweep)---低延迟(并发)
二、G1 GC
1、特点
区域化分代式(并行回收器)
2、目标和原理:
在延迟可控情况下获得尽可能高的吞吐量
堆分成不同的region,不同region代表eden对象(边缘对象) survivor对象 old对象和大对象
每次只清理一部分region,而不是全部
3、适用场景
(1)需要低GC延迟,且有大堆应用程序时
(2)替换掉JDK1.5中CMS的情况
- 超过50%的java堆被活动数据占用
- 对象分配频率或老年代提升频率变化很大
- GC停顿时间过长
4、优点:
(1)并行与并发
(2)分代收集---不同的region
新生代:eden区(边缘区) survivor区
老年代
大对象
(3)空间整合---避免内存碎片化
region之间是复制算法
整体上实际可看作标记-压缩算法
(4)可预测的停顿时间模型 软实时
可明确指定在一个长度为M毫秒时间片内,消耗在垃圾收集的时间不超过N毫秒
指收集部分region
5、G1的三种垃圾回收模式
Young GC--年轻代GC:针对年轻代的垃圾对象的标记和收集
Mixed GC--混合GC:年轻代,老年代的垃圾对象都收集
FUll GC---整个堆的垃圾收集,包括老年代和年轻代的回收
6、垃圾回收的三个过程
(1)年轻代GC--记忆集Rset
年轻代分为eden区、survivor区(s0区和s1区)
每次new对象时,会先放在eden区,
当年轻代的Eden区快满时,就将其中存活的对象移动到s0或s1区(标记--整理法)
当超过15次没被回收时,就放在老年区
[注]年轻代回收暂停所有应用程序
(2)老年代并发标记过程
当堆内存使用达到默认45%时,开始老年代并发标记过程,标记可达对象
(3)混合回收
将老年代存活的对象移动到空闲region区间
然后回收老年代和年轻代的垃圾region
7、记忆集--Remember Set
作用:给每个region一个记忆集Rset,专门用来记录跨代的引用,如新生代的对象,有老年代引用,这样避免遍历新生代对象的时候,还要遍历一边老年代
8、G1调优
(1)三步JVM调优
- 开启G1垃圾回收器---UseG1GC JDK8需要手动设置,9自动设置
- 设置堆内存--Xms Xmx
- 设置最大停顿时间--MaxGCPauseMillis
(2)G1参数
-Xms:初始堆空间内存(默认物理内存的1/64)
-Xmx:最大堆空间内存(默认物理内存的1/4)
-Xmn:设置新生代大小
-XX:NewRatio:设置新生代和老年代的堆结构占比
-XX:SurvivorRatio:设置新生代中Eden和S0 S1空间比例(一般8:2:2)
-XX:MaxTenuringThreshiold:设置新生代垃圾的最大年龄
-XX:+UseG1GC 开启G1垃圾回收器
-XX:G1HeapRegionSize 设置每个Region大小(2的幂)
-XX:MaxGCPauseMillis 设置最大GC停顿时间
-XX:PrallelGCThread 设置STW工作线程数(最多并行垃圾回收线程为8)
-XX:ConcGCThreads 设置并发标记的线程数(并行垃圾回收线程的1/4左右)
-XX:InitiatingHeapOccupancyPercent 设置触发并发GC周期的java堆占用阈值(默认45)
(3) G1优化建议
- 年轻代大小:避免使用 -Xmn,-XX:NewRatio等显示设置年轻代大小,固定大小会覆盖暂停时间目标
- 暂停时间目标不要太过严苛,G1吞吐量的目标是90%的应用程序的时间+10%的垃圾回收时间
JVM调优部分详见:
JVM5--JVM性能优化_@snow'的博客-CSDN博客
三、JDK11后的新垃圾回收器
1、Epsilon
No-Op---无操作GC
2、ZGC
- 可伸缩的低延迟垃圾回收器,尽可能在不影响吞吐量前提下,实现任意堆内存大小都可以将停顿时间限制在10ms以内的低延迟
- 基于Region内存布局,但不设分代,Region动态创建和销毁,容量大小也动态变化
- 采用读屏障、染色指针和内存多重映射等技术实现可并发的标记整理
特别感谢:
尚硅谷宋红康JVM全套教程(详解java虚拟机)_哔哩哔哩_bilibili
待更....