概述:
如果说GC回收算法是方法论,那么垃圾回收器就是落地实现。Java虚拟机规范中对垃圾收集器应该如何实现并没有任何规定,因此不同的厂商、版本的虚拟机所提供的垃圾收集器都可能会有很大差别。
吞吐量(Throughput)
吞吐量就是CPU用于运行用户代码的时间与CPU总消耗时间的比值,即
吞吐量 = 运行用户代码时间 /(运行用户代码时间 + 垃圾收集时间)。
假设用户代码 时间 99 分钟,垃圾回收 时间 1 分钟,那么吞吐量就是 99% 。
停顿时间
停顿时间 指垃圾回收器正在运行时,应用程序 的 暂停时间。对于 独占回收器 而言,停顿时间可能会比较长。使用 并发回收器 时,由于垃圾回收器和应用程序 交替运行,程序的 停顿时间 会变短,但是,由于其 效率 很可能不如独占垃圾回收器,故系统的 吞吐量 可能会较低。
并行和并发
- 串行(Parallel):单线程进行垃圾回收工作,但此时用户线程仍然处于等待状态。
- 并行(Parallel):指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态。
- 并发(Concurrent):指用户线程与垃圾收集线程同时执行(但不一定是并行的,可能会交替执行),用户程序在继续运行。而垃圾收集程序运行在另一个CPU上。
新生代GC(Minor GC)
指发生在新生代的垃圾收集动作,因为Java对象大多都具备朝生夕灭的特性,所以Minor GC非常频繁,一般回收速度也比较快。老年代GC(Major GC)
指发生在老年代的GC,出现了Major GC,经常会伴随至少一次的Minor GC(但非绝对的,在Parallel Scavenge收集器的收集策略里就有直接进行Major GC的策略选择过程)。Major GC的速度一般会比Minor GC慢10倍以上。垃圾收集器种类
如下图所示,大致将垃圾收集器分为新生代和年老代。
新生代收集器
Serial、ParNew、Parallel Scavenge老年代回收器
Serial Old、Parallel Old、CMS整堆回收器
G1
**两种垃圾回收器之间有连线表示它们可以搭配使用,可选的搭配方案如下:
参数 | 新生代垃圾收集器 | 新生代算法 | 老年代垃圾收集器 | 老年代算法 |
---|---|---|---|---|
-XX:UseSerialGC | SerialGC | 复制 | SerialOldGC | 标记整理 |
-XX:+UseParNewGC | ParNew | 复制 | SerialOldGC | 标记整理 |
-XX:+UseParallelGC/ -XX:+UseParallelOldGC |
Parallel[Scavenge] | 复制 | ParallelOld | 标记整理 |
-XX:+UseConcMarkSweepGC | ParNew | 复制 | CMS+SerialOld收集器组合,SerialOld作为CMS出错备用收集器 | 标记清除 |
-XX:UseG1GC | G1整体上用标-清算法 | 局部是复制算法,不会产生内存碎片 |
收集器 | 串行、并行or并发 | 新生代/老年代 | 目标 | 适用场景 |
---|---|---|---|---|
Serial | 串行 | 新生代 | 响应速度优先 | 单CPU环境下的Client模式 |
Serial Old | 串行 | 老年代 | 响应速度优先 | 单CPU环境下的Client模式、CMS的后备预案 |
ParNew | 并行 | 新生代 | 响应速度优先 | 多CPU环境时在Server模式下与CMS配合 |
Parallel Scavenge | 并行 | 新生代 | 吞吐量优先 | 在后台运算而不需要太多交互的任务 |
Parallel Old | 并行 | 老年代 | 吞吐量优先 | 在后台运算而不需要太多交互的任务 |
CMS | 并发 | 老年代 | 响应速度优先 | 集中在互联网站或B/S系统服务端上的Java应用 |
G1 | 并发 | both | 响应速度优先 | 面向服务端应用,将来替换CMS |