垃圾收集器
如果说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现。
下面是Hotspot 虚拟机包含的所有收集器:
Serial
- 特点:是最基本、发展历史最悠久的收集器。这是一个单线程收集器。但它的“单线程”的意义并不仅仅说明它只会使用一个CPU或一条收集线程去完成垃圾收集工作,更重要的是它在进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束。
- 应用年代:新生代
- 采用算法:复制算法
- 应用:是虚拟机运行在Client模式下的默认新生代收集器。
- 优势:简单而高效(与其他收集器的单线程比),对于限定单个CPU的环境来说,Serial收集器由于没有线程交互的开销,专心做垃圾收集自然可以获得最高的单线程效率。
- 缺点:Stop the world!
ParNew
- 特点:ParNew收集器其实就是Serial收集器的多线程版本
- 应用年代:新生代
- 采用算法:复制算法
- 应用:CPU较多
- 优势:除了Serial收集器外,目前只有它能与CMS收集器配合工作。
- 缺点:在单CPU环境,表现甚至不如Serial
Parallel Scavenge
- 特点:Parallel Scavenge收集器的目标是达到一个可控制的吞吐量。(吞吐量 = 运行用户代码时间 + 垃圾收集时间)。他的关注点是尽可能地缩短垃圾收集时用户线程的停顿时间。还可以根据当前系统的运行情况收集性能监测信息,动态调整这些参数以提供最合适的停顿时间或者最大吞吐量。
- 应用年代:新生代
- 采用算法:复制算法
- 优势:同特点
Serial Old
- 特点:Serial 的老年版本
- 应用年代:老年代
- 采用算法:标记-整理
- 应用:与Parallel Scavenge收集器搭配使用;作为CMS收集器的后备预案,在并发收集发生Conurrent Mode Failure 使用。
- 优势:
Parallel Old
- 特点:Parallel Old是Parallel Scavenge收集器的老年代版本
- 应用年代:老年代
- 采用算法:标记-整理
- 应用:注重吞吐量以及CPU资源敏感的场合,都可以优先考虑Parallel
CMS(重点)
- 特点:是HotSpot虚拟机中第一款真正意义上的并发收集器,它第一次实现了让垃圾收集线程与用户线程同时工作。他的关注点在于尽可能地缩短垃圾收集时用户线程的停顿时间。
- 应用年代:老年代
- 采用算法:标记-清除
- 应用场景:大部分集中在互联网站或者B/S系统的服务端上的 Java 应用
- 优势:停顿时间短
它的运作过程相对来说较为复杂,分为 4 个步骤
初始标记、并发标记、重新标记、并发清除
其中,初始标记,重新标记这两个步骤仍然需要“Stop The World”。初始标记仅仅只标记一下GC Roots能直接关联到的对象,速度很快。并发标记阶段就是进行GC Roots Tracing的过程。
重新标记阶段则是为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记几率,这个阶段的停顿时间一般会比初始标记阶段稍长,但远比并发标记时间短。
整个过程耗时最长的阶段是并发标记,并发清除过程,但这两个过程可以和用户线程一起工作。
缺点:
- CMS收集器对CPU资源非常敏感。在并发阶段,它虽然不会导致用户线程停顿,但是会因为占用了一部分线程(或者说CPU资源)而导致应用程序变慢,总吞吐量会降低。
- CMS收集器无法处理浮动垃圾,可能出现“Conurrent Mode Failure”失败而导致另一次 Full GC的产生。由于 CMS 并发清理阶段用户线程还在运行着,伴随程序运行自然就还会产生新的垃圾,这一部分垃圾出现在标记过程之后,CMS无法在档次收集中处理掉它们,只好留待下一次GC时再清理掉。这部分垃圾就称为“浮动垃圾”。因此CMS收集器不能像其他收集器那样等到老年代几乎完全被填满了再进行收集,需要预留一部分空间提供并发收集时程序运作使用。在JDK1.5的默认设置下,CMS 收集器当老年代使用了 68% 的空间后就会被激活。如果预留空间无法满足程序需要,就会出现一次“Concurrent Mode Failure”失败,这时虚拟机将启动后备预案Serial Old。
- CMS是一款基于“标记-清除”算法实现的收集器,所以会有大量空间碎片问题。
更多Java 虚拟机学习
欢迎关注我的个人博客