一、垃圾回收器汇总
GC算法是内存回收的理论方法,GC垃圾收集器则是是内存回收的具体实现。以下是各种垃圾收集器的组合方式。


新生代GC策略和年老代GC策略组合
组合1:Serial + Serial Old
Serial和Serial Old都是单线程进行GC,特点就是GC时暂停所有应用线程。
组合2:Serial CMS + Serial Old
CMS是并发GC,实现GC线程和应用线程并发工作,不需要暂停所有应用线程。另外,当CMS进行GC失败时,会自动使用Serial Old策略进行GC。
组合3:ParNew + CMS
使用-XX:+UseParNewGC选项来开启。ParNew是Serial的并行版本,可以指定GC线程数,默认GC线程数为CPU的数量。可以使用-XX:ParallelGCThreads选项指定GC的线程数。如果指定了选项-XX:+UseConcMarkSweepGC选项,则新生代默认使用ParNew GC策略。
组合4:ParNew + Serial Old
使用-XX:+UseParNewGC选项来开启。新生代使用ParNew GC策略,年老代默认使用Serial Old GC策略。
组合5:Parallel Scavenge + Serial Old
Parallel Scavenge策略主要是关注一个可控的吞吐量:应用程序运行时间 / (应用程序运行时间 + GC时间),可见这会使得CPU的利用率尽可能的高,适用于后台持久运行的应用程序,而不适用于交互较多的应用程序。
组合6:Parallel Scavenge + Parallel Old
Parallel Old是Serial Old的并行版本
组合7:G1GC + G1GC
-XX:+UnlockExperimentalVMOptions
-XX:+UseG1GC #开启
-XX:MaxGCPauseMillis=50 #暂停时间目标
-XX:GCPauseIntervalMillis=200 #暂停间隔目标
-XX:+G1YoungGenSize=512m #年轻代大小
-XX:SurvivorRatio=6 #幸存区比例
二、新生代GC垃圾收集器
新生代GC垃圾收集器简称YGC
2.1 Serial垃圾收集器
2.2 ParNew垃圾收集器
2.3 Parallel Scavenge垃圾收集器
三、老年代GC垃圾收集器
老年代GC垃圾收集器简称FGC
3.1 Serial Old垃圾收集器
3.2 CMS垃圾收集器
3.3 Parallel Old垃圾收集器
四、新老年代GC垃圾收集器 - G1
-XX:+UseG1GC启动G1垃圾收集器,和CMS相比,Gl具备压缩功能,能避免碎片向題,G1的暂停时间更加可控。性能总体还是非常不错的,G1是当今最前沿的垃圾收集器成果之一。
4.1 G1的特点及内存模型
特点:追求极短的停顿时间、多线程GC、面向服务端应用、整体来看基于标记-整理和局部来看基于复制算法合并、不会产生内存空间碎片、可对整个堆进行垃圾回收、可预测的停顿时间。

Eden、Survivor、Old、Humongous,其中,Humongous是特殊的Old类型,专门放置大型对象。
这样的划分方式意味着不需要一个连续的内存空间管理对象。G1将空间分为多个区域,优先回收垃圾最多的区域。G1采用的是Mark-Copy,有非常好的空间整合能力,不会产生大量的空间碎片G1的一大优势在于可预测的停顿时间,能够尽可能快地在指定时间内完成垃圾回收任务在JDK11中,已经将G1设为默认垃圾回收器,通过jstat命令可以查看垃圾回收情况,在YGC时S0/S1并不会交换。
思考题:一个对象和它内部所引用的对象可能不在同一个Region中,那么当垃圾回收时,是否需要扫描整个堆内存才能完整地进行一次可达性分析?
解答:不需要。每个Region都有一个Remembered Set,用于记录本区域中所有对象引用的对象所在的区域,从而在进行可达性分析时,只要在GC Roots中再加上Remembered Set即可防止对所有堆内存的遍历。
4.2 G1垃圾收集过程
步骤1:“初始标记”,标记与GC Roots直接关联的对象,停止所有用户线程,只启动一条初始标记线程,这个过程很快;
步骤2:“并发标记”,进行全面的可达性分析,开启一条并发标记线程与用户线程并行执行.这个过程比较长;
步骤3:“最终标记”,记出并发标记过程中用户线程新产生的垃圾。停止所有用户线程,并使用多条最终标记线程并行执行;
步骤4:“筛选回收”,回收废弃的对象。此时也需要停止一切用户线程,并使用多条筛选回收线程并行执行。

S0/S1的功能由G1中的Survivor region来承载,通过GC日志可以观察到完整的垃圾回收过程如下,其中就有Survivor regions的区域从0个到1个。

红色标识的为G1中的四种region,都处于Heap中。G1执行时使用4个worker并发执行,在初始标记时,还是会触发STW。如第一步所示的Pause。