当前位置:文档之家› 垃圾回收器

垃圾回收器

1 相关知识
1.1 GC的名词
1. 新生代GC(Minor GC)指发生在新生代的垃圾回收动作,因为 Java 对象大多都具备朝生夕死
的特性,所以 Minor GC 通常非常频繁,一般回收速度也比较快。

2. 老年代GC(Major GC)指发生在老年代的垃圾回收动作,出现了 Major GC,经常会伴随至少
一次的 Minor GC(发生这种情况,那么整个堆都 GC 一遍,通常称为 Full GC)。

Major GC 的速度一般会比 Minor GC 慢 10 倍以上。

1.2 并发与并行
1. 串行(Parallel)单线程进行垃圾回收工作,但此时用户线程仍然处于等待状态。

2. 并发(Concurrent)这里的并发指用户线程与垃圾回收线程交替执行。

3. 并行(Parallel)这里的并行指用户线程和多条垃圾回收线程分别在不同CPU上同时工作。

2 垃圾收集器
在下图中,你可以看到不同垃圾回收器适合于不同的内存区域,如果两个垃圾回收器之间存在连线,那么表示两者可以配合使用。

如果当垃圾回收器进行垃圾清理时,必须暂停其他所有的工作线程,直到它完全收集结束。

我们称这种需要暂停工作线程才能进行清理的策略为 Stop-the-World。

Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old 均采用的是 Stop-the-World 的策略。

图中有 7 种不同的垃圾回收器,它们分别用于不同分代的垃圾回收。

新生代回收器:Serial、ParNew、Parallel Scavenge
老年代回收器:Serial Old、Parallel Old、CMS
整堆回收器:G1
2.1 单线程收集器
2.1.1 Serial收集器
串行收集器是最古老,最稳定以及效率高的收集器,可能会产生较长的停顿,只使用一个线程去回收。

新生代、老年代使用串行回收;垃圾收集的过程中会Stop The World(服务暂停)Serial 新生代回收器采用的是复制算法。

2.1.2 Serial Old收集器
Serial Old 回收器是Serial回收器的老生代版本,属于单线程回收器
它使用标记-整理算法。

2.2 多线程垃圾回收器(吞吐量优先)
2.2.1 ParNew收集器
ParNew 回收器是在 Serial 回收器的基础上演化而来的,属于 Serial 回收器的多线程版本,同样运行在新生代区域。

在实现上,两者共用很多代码。

在不同运行环境下,根据 CPU 核数,开启不同的线程数,从而达到最优的垃圾回收效果。

对于那些 Server 模式的应用程序,如果考虑采用 CMS 作为老生代回收器时,ParNew 回收器是一个不错的选择。

ParNew 新生代回收器采用的是复制算法。

2.2.2 Parallel收集器
和 ParNew 回收一样,Parallel Scavenge 回收器也是运行在新生代区域,属于多线程的回收器。

但不同的是,ParNew 回收器是通过控制垃圾回收的线程数来进行参数调整,而 Parallel Scavenge 回收器更关心的是程序运行的吞吐量。

即一段时间内,用户代码运行时间占总运行时间的百分比。

Parallel Scavenge 新生代回收器采用的是复制算法。

2.2.3 Parallel Old 收集器
Parallel Old 回收器是 Parallel Scavenge 回收器的老生代版本,属于多线程回收器,采用标记-整理算法。

Parallel Old 回收器和 Parallel Scavenge 回收器同样考虑了吞吐量优先这一指标,非常适合那些注重吞吐量和 CPU 资源敏感的场合。

Parallel Old 老年代回收器采用的是标记 - 整理算法。

2.3 其他的回收器(停顿时间优先)
2.3.1 CMS收集器
CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。

CMS收集器是基于“标记-清除”算法实现的,它的运作过程相对于前面几种收集器来说要更复杂一些,整个过程分为4个步骤,包括:
初始标记(CMS initial mark)
初始标记仅仅是标记 GC Roots 内直接关联的对象。

这个阶段速度很快,需要 Stop the
World。

并发标记(CMS concurrent mark)
并发标记进行的是 GC Tracing,从 GC Roots 开始对堆进行可达性分析,找出存活对象。

重新标记(CMS remark)
而避免全堆扫描。

2. Root Region Scanning,程序运行过程中会回收survivor区(存活到老年代),这一过程必须在young GC之前完成。

3. Concurrent Marking,在整个堆中进行并发标记(和应用程序并发执行),此过程可能被young GC 中断。

在并发标记阶段,若发现区域对象中的所有对象都是垃圾,那个这个区域会被立即回收(图中打X)。

同时,并发标记过程中,会计算每个区域的对象活性(区域中存活对象的比例)。

4. Remark, 再标记,会有短暂停顿(STW)。

再标记阶段是用来收集并发标记阶段产生新的垃圾(并发阶段和应用程序一同运行);G1中采用了比CMS更快的初始快照算法:snapshot-at-the-beginning (SATB)。

5. Copy/Clean up,多线程清除失活对象,会有STW。

G1将回收区域的存活对象拷贝到新区域,清除Remember Sets,并发清空回收区域并把它返回到空闲区域链表中。

6. 复制/清除过程后。

回收区域的活性对象已经被集中回收到深蓝色和深绿色区域。

相关主题