JVM学习笔记5-HotSpot垃圾收集器详解
相关概念
并发和并行
这两个名词都是并发编程中的概念,在谈论垃圾收集器的上下文语境中,它们可以解释如下。
并行(Parallel):指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态。
并发(Concurrent):指用户线程与垃圾收集线程同时执行(但不一定是并行的,可能会交替执行),用户程序在继续运行,而垃圾收集程序运行于另一个CPU上。
Minor GC 和 Full GC
新生代GC(Minor GC):指发生在新生代的垃圾收集动作,因为Java对象大多都具备朝生夕灭的特性,所以Minor GC非常频繁,一般回收速度也比较快。
老年代GC(Major GC / Full GC):指发生在老年代的GC,出现了Major GC,经常会伴随至少一次的Minor GC(但非绝对的,在Parallel Scavenge收集器的收集策略里就有直接进行Major GC的策略选择过程)。Major GC的速度一般会比Minor GC慢10倍以上。
吞吐量
吞吐量就是CPU用于运行用户代码的时间与CPU总消耗时间的比值,即
吞吐量 = 运行用户代码时间 /(运行用户代码时间 + 垃圾收集时间)。
虚拟机总共运行了100分钟,其中垃圾收集花掉1分钟,那吞吐量就是99%。
-----------------------我是分割线------------------
HotSpot虚拟机提供了多种垃圾收集器如下图,橙色部分代表新生代,绿色部分代表老年代;如果两个收集器之间存在连线,就说明他们可以搭配使用。每种收集器都有各自的特点,没有最好的垃圾收集器,只有最适合的垃圾收集器。我们可以根据自己实际的应用需求选择最适合的垃圾收集器。
根据新生代和老年代各自的特点,我们应该分别为它们选择不同的收集器,以提升垃圾回收效率。
新生代垃圾收集器
1. Serial垃圾收集器
单线程
适合客户端应用
简单高效
采用“复制”算法
下图展示了Serial/Serial Old收集器的运行过程
2. ParNew垃圾收集器
ParNew是Serial的多线程版本。
适合多CPU的服务器环境
与Serial性能对比
采用“复制”算法
-
追求“降低停顿时间”
ParNew收集器的工作过程如下图所示:
3. Parallel Scavenge垃圾收集器
Parallel Scavenge和ParNew一样都是多线程、新生代收集器,都使用“复制”算法进行垃圾回收。但它们有个巨大的不同点:ParNew收集器追求降低用户线程的停顿时间,因此适合交互式应用;而Parallel Scavenge追求CPU吞吐量,能够在较短的时间内完成指定任务,因此适合没有交互的后台计算。
什么是“吞吐量”?
降低停顿时间的两种方式
Parallel Scavenge提供的参数
设置“吞吐量”
设置“停顿时间”
启用自适应调节策略
老年代垃圾收集器
1. Serial Old垃圾收集器
Serial Old收集器是Serial的老年代版本,它们都是单线程收集器,也就是垃圾收集时只启动一条GC线程,因此都适合客户端应用。
它们唯一的区别就是Serial Old工作在老年代,使用“标记-整理”算法;而Serial工作在新生代,使用“复制”算法。
2. Parallel Old垃圾收集器
Parallel Old收集器是Parallel Scavenge的老年代版本,一般它们搭配使用,追求CPU吞吐量。
3. CMS垃圾收集器
CMS收集器是一款追求停顿时间的老年代收集器,它在垃圾收集时使得用户线程和GC线程并行执行,因此在垃圾收集过程中用户也不会感受到明显的卡顿。但用户线程和GC线程之间不停地切换会有额外的开销,因此垃圾回收总时间就会被延长。
垃圾回收过程
初始标记
并发标记
重新标记
并发清除
其工作过程如下图:
CMS的缺点
吞吐量低
无法处理浮动垃圾,导致频繁Full GC
使用“标记-清除”算法产生碎片空间
开启-XX:+UseCMSCompactAtFullCollection
设置参数-XX:CMSFullGCsBeforeCompaction
通用垃圾收集器——G1垃圾收集器
G1是目前最牛逼的垃圾收集器。
G1的特点
追求停顿时间
多线程GC
面向服务端应用
标记-整理和复制算法合并
可对整个堆进行垃圾回收
可预测停顿时间
G1的内存模型
G1垃圾收集器没有新生代和老年代的概念了,而是将堆划分为一块块独立的Region。当要进行垃圾收集时,首先估计每个Region中的垃圾数量,每次都从垃圾回收价值最大的Region开始回收,因此可以获得最大的回收效率。
Remembered Set
一个对象和它内部所引用的对象可能不在同一个Region中,那么当垃圾回收时,是否需要扫描整个堆内存才能完整地进行一次可达性分析?
当然不是,每个Region都有一个Remembered Set,用于记录本区域中所有对象引用的对象所在的区域,从而在进行可达性分析时,只要在GC ROOTs中再加上Remembered Set即可防止对所有堆内存的遍历。
G1垃圾收集过程
初始标记
并发标记
最终标记
筛选回收
G1的工作过程如下图:
垃圾收集器常用参数总结
client/serrver端不同的GC方式:
Sun JDK HotSpot虚拟机GC组合方式:
本文根据周志明著《深入理解Java虚拟机》及网上相关资料整理,点击阅读原文查看购书链接。