上一篇文章着重介绍了垃圾收集的相关算法及其概念,本篇文章将会介绍JVM中的各种收集器,了解各种收集器是如何利用收集算法进行垃圾回收的。
一、Serial收集器
这种收集器是一个单线程的收集器。
适用回收区域:年轻代
使用回收算法:复制算法
回收时用户线程是否停止:是
可以结合使用的老年代收集器:CMS,Serial Old,Paralled Old
适合使用的场景:运行在Client模式下的虚拟机
特点:简单而且高效
二、ParNew收集器
这种收集器是Serial收集器的多线程版本
适用回收区域:年轻代
使用回收算法:复制算法
回收时用户线程是否停止:是
可以结合使用的老年代收集器:CMS,Serial Old
适合使用的场景:多CPU环境
特点:有效利用多CPU的系统资源,默认开启回收线程与CPU数量相同,通过-XX:ParallelGCThreads参数限制垃圾回收线程数,存在多线程的切换开销
三、Parallel Scavenge收集器
这种收集器是一种并行的多线程收集器,它为了达到一个可以控制的吞吐量。
吞吐量:CPU运行代码时间与CPU总消耗时间的比值。即(运行代码时间)/(运行代码时间+垃圾收集时间)
使用回收算法:复制算法
回收时用户线程是否停止:是
可以结合使用的老年代收集器:Serial Old,Parallel Old
适合使用的场景:后台运算而且不太需要与用户交互的任务
特点:拥有GC自适应的调节策略,开启-XX:+UseAdaptiveSizePolicy参数会是虚拟机自动最合适的停顿时间或者最大的吞吐量
四、Serial Old收集器
这种收集器是Serial收集器的老年代版本,也是单线程收集器。
使用回收算法:标记-整理算法
回收时用户线程是否停止:是
可以结合的年轻代收集器:Parallel Scavenge
适合的场景:虚拟机运行在Client的模式下
特点:简单高效
五、Parallel Old 收集器
这种收集器是Parallel Scavenge收集器的老年代版本,使用多线程进行回收
使用回收算法:标记-整理算法,jdk1.6才提供
回收时用户线程是否停止:是
可以结合的年轻代收集器:Parallel Scavenge
适合场景:注重吞吐量以及CPU资源敏感的场合
特点:吞吐量优先
六、CMS收集器
这种收集器是一种以获取最短停顿时间为目标的收集器。
使用回收算法:标记清除算法
过程包含:初始标记-》并发标记-》重新标记-》并发清除
初始标记、重新标记:停顿用户线程,初始标记标记GC Roots可以直接关联的对象,速度很快。重新标记是修正并发标记期间因用户程序继续运行而导致标记产生变动那些记录。
适合场景:重视服务的相应速度,系统系统停顿时间最短,以给用户带来最好的体验。
优点:并发收集,低停顿
缺点:对CPU资源非常敏感,因为是并发收集,会暂用用户线程运行机会,默认启用回收线程数:(CPU数量+3)/4
第二个缺点是无法处理浮动垃圾,那些在并发清理阶段用户线程产生的垃圾只能在下次垃圾回收时候回收
第三个缺点是由于使用标记清除算法,回收结束后会产生大量空间碎片
七、G1 收集器 Garbage-First
这是一种支持对年轻代,老年代进行回收的线程,有希望完全取代CMS收集器,面向服务的的收集器
特点:并发与并行:利用多CPU,多核硬件优势使用多个CPU来缩短停顿时间
分代收集:同样采用分代思想
空间整合:结合标记整理算法与复制算法,回收后不会产生碎片,可以提供规整的内存空间,避免了大对象找不到连续空间而触发下一次GC
可预测停顿时间:后台维护一个优先列表,每次根据允许的收集时间优先回收价值最大的Region
内存分配策略:
内存分配策略:
1、对象优先在Eden区分配
2、大对象直接进入老年代
3、长期存活的对象将进入老年代
4、动态对象年龄判断
5、空间分配担保
VM 参数列表:
1、-XX:+PrintGCDetails JDK10已经过期,使用-Xlog:gc* 代替.