垃圾收集器
图中展示了七种作用于不同分代的收集器,如果两个收集器之间存在连线,就说明它们可以搭配使用。在JDK8时将Serial+CMS,ParNew+Serial Old这两个组合声明为废弃,并在JDK9中完全取消了这些组合的支持
并行和并发都是并发编程中的专业名词,在谈论垃圾收集器的上下文语境中, 它们可以理解为
并行(Parallel):指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态 并发(Concurrent):指用户线程与垃圾收集线程同时执行
Serial收集器
新生代,标记-复制算法,单线程。进行垃圾收集时,必须暂停其他所有工作线程,直到它收集结束
ParNew收集器
ParNew本质上是Serial收集器的多线程并行版本
Parallel Scavenge收集器
新生代,标记复制算法,多线程,主要关注吞吐量 吞吐量=运行用户代码时间/(运行用户代码时间+运行垃圾收集时间)
Serial Old收集器
老年代,标记-整理算法,单线程,是Serial收集器的老年代版本
用处有如下2个
- 在JDK5以及之前的版本中与Parallel Scavenge收集器搭配使用
- 作为CMS收集器发生失败时的后备预案,在并发收集发生Concurrent Mode Failure时使用
Parallel Old收集器
老年代,标记-整理算法,多线程,是Parallel Scavenge收集器的老年代版本
在注重吞吐量或者处理器资源较为稀缺的场合,都可以优先考虑Parallel Scavenge加Parallel Old收集器这个组合
CMS收集器
老年代,标记-清除算法,多线程,主要关注延迟
运作过程分为4个步骤
- 初始标记(CMS initial mark)
- 并发标记(CMS concurrent mark)
- 重新标记(CMS remark)
- 并发清除(CMS concurrent sweep)
- 初始标记:标记一下GC Roots能直接关联到的对象,速度很快(这一步会发生STW)
- 并发标记:从GC Roots的直接关联对象开始遍历整个对象图的过程,这个过程耗时较长但是不需要停顿用户线程,可以与垃圾收集一起并发运行
- 重新标记:为了修正并发标记期间,因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录(就是三色标记法中的增量更新,这一步也会发生STW)
- 并发清除:清理删除掉标记阶段判断的已经死亡的对象,由于不需要移动存活对象,所以看这个阶段也是可以与用户线程同时并发的
总结
收集器 | 收集对象和算法 | 收集器类型 | 说明 | 适用场景 |
---|
Serial | 新生代,复制算法 | 单线程 | | 简单高效;适合内存不大的情况 | ParNew | 新生代,复制算法 | 并行的多线程收集器 | ParNew垃圾收集器是Serial收集器的多线程版本 | 搭配CMS垃圾回收器的首选 | Parallel Scavenge吞吐量优先收集器 | 新生代,复制算法 | 并行的多线程收集器 | 类似ParNew,更加关注吞吐量,达到一个可控制的吞吐量 | 本身是Server级别多CPU机器上的默认GC方式,主要适合后台运算不需要太多交互的任务 |
收集器 | 收集对象和算法 | 收集器类型 | 说明 | 适用场景 |
---|
Serial Old | 老年代,标记整理算法 | 单线程 | | Client模式下虚拟机使用 | Parallel Old | 老年代,标记整理算法 | 并行的多线程收集器 | Paraller Scavenge收集器的老年代版本,为了配置Parallel Svavenge的面向吞吐量的特性而开发的对应组合 | 在注重吞吐量以及CPU资源敏感的场合采用 | CMS | 老年代,标记清除算法 | 并行与并发收集器 | 尽可能的缩短垃圾收集时用户线程停止时间;缺点在于,1.内存碎片,2.需要更多CPU资源,3.浮动垃圾问题,需要更大的堆空间 | 重视服务的相应速度,系统停顿时间和用户体验的互联网网站或者B/S系统。互联网后端目前cms是主流的垃圾回收器 | G1 | 跨新生代和老年代;标记整理+化整为零 | | 并行与并发收集器 | JDK1.7才正式引入,采用分区回收的思维,基本不牺牲吞吐量的前提下完成低停顿的内存回收;可预测的停顿是其最大的优势 |
参考博客
[1]https://zhuanlan.zhihu.com/p/375977480 [2]https://www.jianshu.com/p/671495682e46 [3]https://www.zhihu.com/question/431264970/answer/1586591296
|