谈谈JVM GC 收集器

本文介绍了JVM垃圾收集器的发展,重点关注分代收集器(如Serial New、Parallel Scavenge和CMS)和非分代收集器(如G1和ZGC)。分代收集器中的Parallel Scavenge注重吞吐量,CMS提供并发收集,而G1作为不分代收集器,实现了低延迟和大堆管理。ZGC作为新的实验性收集器,目标是实现近乎零停顿时间,具备无碎片、可扩展性和超大堆支持。
摘要由CSDN通过智能技术生成

前言:

目前已经发展到jdk11了。很多资料上的垃圾收集器还停留在1.7以前。本文基于收集器的发展路线,从前到后汇总和简单分析一下JVM垃圾收集器的roadmap。本文暂且从对内存区管理和回收特色方面分为分代收集和非分代两个part。

 

Part I、分代收集阶段

一、新生代收集器

1.Serial New

这是最早的新生代收集器,也是jdk1.5之前默认的收集器,在GC log里可以经常看到[DefNew 的字样,说的就是这个收集器。它是基于复制算法(算法不在本文描述范畴)实现的,单线程,而且需要stop the world,所以新生代不能太大,否则对于停顿来讲是比较影响交互响应的。

2.Parallel New

这是对单线程的Serial的一种改进,ParNew收集器是并行的,在多CPU的场景下会有比串行收集器更好的性能,除此之外,实现算法跟Serial完全一样。这种收集器在采用CMS(后文会讲到,一种老年代收集器)时,默认新生代会采用ParNew收集器。需要注意的是,如果CPU数量为1个或者少于4个时,该种收集器的性能并不会比Serial要好。因为除去上下文切换,以及占用用户线程CPU时间片,导致用户线程被拖慢。

3.Parallel Scavenge

这也是一种新生代垃圾收集器,PSYoungGen它采用的也是复制算法,它与前两种收集器最大的区别是,它关注的是吞吐量而不是延迟。也被称为是吞吐量优先的收集器。其中,吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)。主要使用场景:主要适合在后台运算而不是太多交互的任务,高吞吐量则可以最高效率的利用CPU时间,尽快的完成程序的运算任务。当然,如果想要降低停顿时间,相应的也会影响吞吐量。几个重要的参数:

  • 控制最大垃圾收集停顿时间的-XX:MaxGCPauseMillis参数

MaxGCPauseMillis参数允许的值是一个大于0的毫秒数,收集器将尽力保证内存回收花费的时间不超过设定值。不过大家不要异想天开地认为如果把这个参数的值设置得稍小一点就能使得系统的垃圾收集速度变得更快,GC停顿时间缩短是以牺牲吞吐量和新生代空间来换取的:系统把新生代调小一些,收集300MB新生代肯定比收集500MB快吧,这也直接导致垃圾收集发生得更频繁一些,原来10秒收集一次、每次停顿100毫秒,现在变成5秒收集一次、每次停顿70毫秒。停顿时间的确在下降,但吞吐量也降下来了。

  • 设置吞吐量大小的 -XX:GCTimeRatio参数。

GCTimeRatio参数的值应当是一个大于0小于100的整数,也就是垃圾收集时间占总时间的比率,相当于是吞吐量的倒数。如果把此参数设置为19,那允许的最大GC时间就占总时间的5%(即1 /(1+19)),默认值为99,就是允许最大1%(即1 /(1+99))的垃圾收集时间。

  • 自适应策略开关UseAdaptiveSizePolicy参数。

-XX:+UseAdaptiveSizePolicy是一个开关参数,当这个参数打开之后,就不需要手工指定新生代的大小(-Xmn)、Eden与Survivor区的比例(-XX:SurvivorRatio)、晋升老年代对象年龄(-XX:PretenureSizeThreshold)等细节参数了,虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或最大的吞吐量,这种调节方式称为GC自适应的调节策略(GC Ergonomics)

在实现上比前两种改进了很多,但是一直到1.6以后才真正用起来,这是因为,它不能跟CMS收集器一起配合工作。在此之前,使用该种新生代收集器的话,老年代收集器必须使用Serial Old收集器。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值