垃圾回收器性能指标
以上三点构成不可能三角,即一款垃圾回收器不可能同时满足三点。随着硬件水平的提升,内存占用不再是我们关注的重点,评估垃圾回收器性能时,重点关注吞吐量和暂停时间。吞吐量和暂停时间是相互矛盾的,目前我们追求的效果是:在最大吞吐量优先的情况下,减小暂停时间。
垃圾回收器发展历史
垃圾回收器组合
7款经典垃圾回收器之间的组合关系:
说明:
- 两个回收器间有连线,说明它们可以搭配使用;
- Serial Old作为CMS出现“Concurrent Mode Failure”失败的后备预案;
- G1可用于新生代和老年代;
- 红色虚线连线:JDK 8将这两组组合声明为废弃,并在JDK 9中完全移除;
- 绿色虚线连线:JDK 14中,弃用了该组合;
- 绿色虚线边框:JDK 14中,删除了CMS。
默认垃圾回收器查看
编写一段简单的java程序:
public class Test { public static void main(String[] args) { System.out.println("hello"); } }
添加-XX:+PrintCommandLineFlagsJVM参数配置,在JDK 8环境下程序输出:
-XX:InitialHeapSize=536870912 -XX:MaxHeapSize=8589934592 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC hello
-XX:+UseParallelGC说明JDK 8默认的垃圾回收器为Parallel。
在JDK 9环境下输出:
-XX:G1ConcRefinementThreads=10 -XX:InitialHeapSize=536870912 -XX:MaxHeapSize=8589934592 -XX:+PrintCommandLineFlags -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC hello
-XX:+UseG1GC说明JDK 9默认的垃圾回收器为G1。
经典垃圾回收器介绍
Serial、Serial Old回收器
Serial垃圾回收器为单线程串行回收器,为HotSpot中Client模式下默认的新生代垃圾回收器,采用复制算法、串行回收和STW机制进行内存回收;
Serial Old垃圾回收器为Serial提供的老年代垃圾回收器,采用标记压缩算法、串行回收和STW机制进行内存回收:
Serial适用于运行在Client模式下的虚拟机或者内存不大(几十MB到一两百MB)的环境下,因为是串行的,有较长时间的STW,所以并不适用于要求快响应、交互较强的应用。
可以通过XX:+UseSerialGC参数启用Serial回收器,表示新生代使用Serial,老年代使用Serial Old。
ParNew回收器
ParNew是Parallel New两个词的简写,是Serial的多线程版本垃圾回收器。ParNew是很多JVM运行在Server模式下新生代的默认垃圾回收器,采用复制算法,并行回收和STW机制进行内存回收。
可以通过XX:+UseParNewGC参数启用ParNew回收器,表示新生代使用ParNew,老年代不受影响。
Serial、ParNew搭配Serial Old回收器示意图:
图片来自于
https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/691189/
Parallel、Parallel Old回收器
Parallel Scavenge回收器也是作用于新生代,同样采用复制算法,并行回收和STW机制。
Parallel Scavenge和ParNew对比:
JDK 1.6提供了用于老年代的并行垃圾回收器 —— Parallel Old回收器,用于替代Serial Old回收器。Parallel采用标记压缩、并行回收和STW机制。
可以通过-XX:+UseParallelGC指定新生代使用Parallel Scavenge回收器;-XX:+UseParallelOldGC指定老年代使用Parallel Old回收器,它们是成对存在的,开启一个另一个也会开启。
此外还可以通过-XX😛arallelGCThreads=设置并行回收器的线程数:
-XX:+UseAdaptiveSizePolicy开启Parallel Scavenge的自适应调节策略:
CMS回收器
JDK 1.5 HotSpot推出了一款真正意义上的并发回收器 —— CMS(Concurrent-Mark-Sweep),第一次实现了让垃圾回收线程和用户线程同时工作。CMS的关注点在于尽可能缩短垃圾收集时用户线程停顿的时间。
CMS作为一款老年代的垃圾回收器,不能和新生代垃圾回收器Parallel Scavenge搭配使用,只能和ParNew或者Serial搭配使用。
CMS回收器示意图:
图片来自于
https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/691189/
主要分为以下几个步骤:
- 初始标记(Initial-Mark):所有用户线程暂停(STW),这个阶段仅仅标记出GC Roots能直接关联到的对象,所以速度非常快,STW时间很短;
- 并发标记(Concurrent-Mark):该阶段从GC Roots直接关联对象开始遍历整个对象链,虽然这个过程耗时较长,但并不需要暂停用户线程,并发执行,没有STW;
- 重新标记(Remark):由于上一步用户线程也在执行,所以这一步用于修正因用户线程继续运行而导致标记发生变动的那一部分对象的标记记录。这个阶段会比初始标记阶段耗时长一点,但远比并发标记阶段低;
- 并发清除(Concurrent-Sweep):该阶段清理删除垃圾,回收空间。由于没有移动对象,所以该阶段也不需要STW。
CMS的优缺点都很明显:
优点:
缺点:
此外,CMS在回收过程中,因为用户线程并没有中断,所以还需确保用户线程有足够的内存可用。换句话说,CMS回收器不能等老年代即将被填满时才去回收,而应当堆内存使用率到达一定阈值时,便开始进行回收。如果CMS运行期间预留内存不足,就会出现一次“Concurrent Mode Failure”失败,虚拟机会启动后备方案,临时启用Serial Old回收器来完成老年代的垃圾回收。
CMS回收器可设置参数:
G1回收器
G1(Garbage First)回收器把堆内存分割成很多不相关的区域(region,物理上不连续),使用不同区域来表示伊甸园区,幸存者区和老年代。
G1会避免对整个Java堆进行垃圾收集,它会跟踪各个region里垃圾回收的价值大小(回收所获得的空间大小及所需时间的经验值),在后台维护一个优先列表,每次根据允许收集时间,优先回收价值最大的region。
region的说明
图片来自于
https://tech.meituan.com/2016/09/23/g1.html
G1回收垃圾过程如下图所示:
图片来自于
https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/691189/
主要分为以下几个步骤:
- 初始标记:仅仅是标记GC Roots能直接关联的对象,需要STW,但这个过程非常快;
- 并发标记:从GC Roots出发,对堆中对象进行可达性分析,找出存活对象,该阶段耗时较长,但是可与用户线程并发执行;
- 最终标记:主要修正在并发标记阶段因为用户线程继续运行而导致标记记录产生变动的那一部分对象的标记记录,需要STW;
- 筛选回收:将各个region分区的回收价值和成本进行排序,根据用户所期望的停顿时间制定回收计划。这阶段停顿用户线程,STW。
G1回收器的优缺点:
优点:
缺点:
G1回收器相关参数设置:
总结
上面这几款经典的垃圾回收器各有特点,具体使用的时候需要根据具体的情况选用不同的垃圾回收器:
垃圾回收器 |
分类 |
作用位置 |
使用算法 |
特点 |
适用场景 |
Serial |
串行 |
新生代 |
复制算法 |
响应速度优先 |
适用于单CPU环境下的Client模式 |
ParNew |
并行 |
新生代 |
复制算法 |
响应速度优先 |
多CPU环境Server模式下与CMS配合使用 |
Parallel |
声明:本站部分文章内容及图片转载于互联 、内容不代表本站观点,如有内容涉及侵权,请您立即联系本站处理,非常感谢!
赞 (0)
吸拖一体,还带自清洗-云米智能洗地机Cyber使用效果真不错
上一篇
2021年11月3日
专业风机制造品牌,推动绿色建设发展
下一篇
2021年11月3日
|