垃圾收集器的类型
从不同角度分析垃圾收集器,可以分为不同的类型:
1、按线程数分
串行收集器
串行收集器一次使用一个线程进行垃圾回收
并行收集器
并行收集器一次开启多个线程进行垃圾回收,在并行能力较强的CPU上,使用并行收集器可以缩短GC的停顿时间。
2、按工作模式分
并发式收集器
并发式收集器与应用程序交替进行,以尽可能的减少应用程序的停顿时间
独占式收集器
独占式收集器一旦运行,将停止应用程序的其他所有线程,知道垃圾回收过程完全结束。
3、按碎片处理方式
压缩式收集器
压缩式收集器会在回收完成后,对存活的对象进行压缩整理,消除回收后的碎片
非压缩式收集器
非压缩式收集器回收垃圾对象后,不进行内存压缩整理,会产生碎片
4、按工作内存区间
新生代收集器
新生代收集器只在新生代工作
老年代收集器
老年代收集器只在老年代工作
新生代串行收集器
单线程垃圾回收,独占式垃圾回收。串行收集器运行,所有应用程序线程停止,产生Stop the World。
新生代串行收集器采用复制算法,在单核CPU或者较小的应用内存等硬件平台不是特别优越的场合,性能表现可以超过并行收集器。
在Hot Spot虚拟机中,-XX:+UseSerialGC 参数可以指定使用新生代串行收集器和老年代串行收集器。
新生代串行收集器的GC标识为DefNew。
老年代串行收集器
使用标记-压缩算法,也是单线程、独占式的垃圾回收。老年代串行收集器在GC的标识为Tenured。
并行收集器
串行收集器的多线程化,回收策略、算法、参数和串行收集器一样。并行收集器也是独占式的,垃圾回收时,应用程序暂停工作。使用多线程进行垃圾收集
开启并行收集器参数:
-XX:+UseParNewGC: 新生代使用并行收集器,老年代使用串行收集器。
-XX:+UseConcMarkSweepGC: 新生代使用串行收集器,老年代使用CMS
-XX:+UseParallelGC: 新生代使用并行收集器,老年代使用串行收集器。
指定并行收集器线程数:
-XX:ParallelGCThreads: 一般等于CPU数.
并行收集器的GC标识为ParNew。
新生代并行收集器
多线程、独占式,采用复制算法,关注系统吞吐量。
参数启用:
-XX:+UseParallelGC 新生代使用并行收集器,老年代使用串行收集器。
-XX:+UseParallelOldGC 新生代和老年代都是用并行收集器。
其他参数:
-XX:MaxGCPauseMillis: 设置最大垃圾收集停顿时间。(大于0的整数)
-XX:GCTimeRatio: 设置吞吐量大小(0~100的整数)
-XX:+UseAdaptiveSizePolicy 自适应GC策略,新生代大小、eden和survivor的比例、老年代晋升年龄等自动调整。
新生代并行收集器的GC标识:PSYoungGen
老年代并行收集器
标记-压缩算法、多线程。
参数:
-XX:+UseParallelOldGC 新生代和老年代都是用并行收集器。关注系统吞吐量
老年代并行收集器的GC标识:ParOldGen
CMS收集器
并行收集器关注吞吐量,CMS(Concurrent Mark Sweep)收集器关注停顿时间,使用标记-清除算法。也是多线程并行的收集器。
工作步骤:
初始标记、并发标记、重新标记、并发清楚、并发重置
出事标记和重新标记是独占系统资源的,其他步骤是和应用程序线程并行的。
参数:
-XX:ParallelCMSThreads: 设置CMS线程数。
CPU资源紧张,CMS收集器的性能会很糟糕。当堆内存使用率达到某一阈值才进行垃圾收集,以确保应用程序依然有足够的空间运行。
-XX:CMSInitiatingOccupancyFraction: 默认68,即老年代空间使用率达到68%进行CMS回收。内存使用率增长过快使CMS过程出现内存不足、CMS失效,JVM将启用老年代串行收集器。
-XX:+UseCMSCompactAtFullCollection CMS后进行碎片整理
-XX:CMSFullGCsBeforeCompaction: 多少次CMS进行一次内存压缩。
参考:
《Java程序性能优化 让你的Java程序更快、更稳定》