现代垃圾收集器,大多数都采用分代回收的方式,所以,本文以年轻代和老年代的垃圾收集器进行分类归纳:
年轻代垃圾收集器:
Serial 垃圾收集器
只有一条GC线程处理垃圾回收,垃圾回收过程中会STW 。适合客户端,单CPU的场景。
应用在新生代,采用复制算法
ParNew 垃圾收集器
ParNew 是Serial 的多线程版本。多条GC线程并行进行垃圾回收,充分利用CPU资源,但回收过程中仍然会STW。适合多CPU场景。在单CPU场景,多线程并行GC会引起上下文切换,性能不高。
Parallel Scavenge 垃圾收集器
另一个版本的多线程GC收集器,追求吞吐量优先。吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间),比如JVM运行100分钟,垃圾回收1分钟,那么吞吐量就是99%。
Parallel Scavenge收集器提供了两个参数用于精确控制吞吐量,分别是控制最大垃圾收集停顿时间的-XX:MaxGCPauseMillis参数以及直接设置吞吐量大小的-XX:GCTimeRatio参数,也就是说主要从停顿时间来控制,具体可以查一下这些参数的含义。
Scavenge收集器有一个-XX:+UseAdaptiveSizePolicy参数,这是一个开关参数,这个参数打开之后,就不需要手动指定新生代大小、Eden区和Survivor参数等细节参数了,虚拟机会根据当前系统的运行情况手机性能监控信息,动态调整这些参数以提供最合适的停顿时间或者最大的吞吐量。
与ParNew的区别:
1.Parallel Scavenge :追求吞吐量。使用无交互的应用,比如批处理应用
2.ParNew:追求降低用户停顿时间
老年代垃圾收集器:
Serial Old 垃圾收集器
单线程收集器,使用标记-整理算法,清理老年代。
Parallel Old 垃圾收集器
Parallel Old是Parallel Scavenge的老年代版本,追求吞吐量优先。使用的是标记-整理算法。
CMS 垃圾收集器
CMS 收集器追求获取最短GC停顿时间为目标。它在垃圾回收时,使得用户线程和GC线程时并发执行的,因此即使存在垃圾回收,用户也不会感觉到明显的卡顿。在回收老年代时,使用的是标记-清除算法,所以会有内存碎片问题。
在JVM中配置使用垃圾收集器
事实上,JVM是混合地组合使用以上垃圾收集器,作用于新生代和老年代,如以下参数:
-XX:+UseSerialGC 年轻代和老年代都用串行收集器
-XX:+UseParNewGC 年轻代使用 ParNew,老年代使用 Serial Old
-XX:+UseParallelGC 年轻代使用 ParallerGC,老年代使用 Serial Old
-XX:+UseParallelOldGC 新生代和老年代都使用并行收集器
-XX:+UseConcMarkSweepGC,表示年轻代使用 ParNew,老年代的用 CMS
-XX:+UseG1GC 使用 G1垃圾回收器
-XX:+UseZGC 使用 ZGC 垃圾回收器