JVM高级特性-六、七大垃圾收集器介绍
前言:
之前已经介绍过垃圾收集算法,没看过的同学可以查看之前的文章:JVM高级特性-四、垃圾收集算法。
垃圾收集算法是垃圾回收的方法,而垃圾收集器就是对垃圾收集的具体实现。不同厂商对于垃圾收集的实现方式各不相同,
这里主要介绍的jdk1.7只有的hotspot虚拟机,这个虚拟机主要包含如下收集器
年轻代(young generation):serial、ParNew、Parrallel Scanvenge
老年代(tenured generation):cms、serial Old、parrallel Old
兼顾young和tenured:G1
其中,G1收集器时相对较新的收集器,下面将逐个介绍个收集器
一、Serial收集器
serial收集器时一个串行收集器,在执行垃圾回收时必须停止所有线程
新生代采用复制算法,老年代采用标记整理算法
是client模式下默认的新生代垃圾收集器
优点:简单高效,由于没有线程交互开销,在单个CPU环境下运行获得最高回收效率
二、ParNew
parnew收集器是Serial的多线程版本,收集算法、可控制的配置参数、对象分配规则
回收策略等都与Serial一样,两者也使用了许多共同的代码
是server模式下首选的新生代收集器
只有serial与parnew可以与cms收集器配合使用,cms收集器会在后面段落具体介绍
三、Parallel scavenge
ps收集器是一个新生代收集器,与Parnew一样,是多线程的垃圾收集器,也是采用复制算法
看起来与Parnew没什么不同,但其实他有自己的特点,他主要为能控制吞吐量而开发的一款收集器
吞吐量,就是CPU运行用户代码的时间与CPU运行总时间的比值,即吞吐量=运行用户代码时间/(运行用户代码时间+垃圾回收时间)
ps收集器的两个关键参数:MaxGCPauseMillis和GCTimeRatio
MaxGCPauseMillis:用于控制收集器最大垃圾回收时间
GCTimeRatio:用于控制吞吐量,即最大gc时间占比,例如设置参数为19,则gc时间占比为 1/(19+1),结果为5%。
四、Serial Old
so收集器是Serial的老年代版本,主要作为client模式下的虚拟机使用
在server模式下主要有两个作用:
1.作为jdk1.5及之前版本中与parallel scavenge搭配使用
2.作为cms收集器的后备方案,当cms收集器发生concurrent mode failure时使用
五、Parallel Old
po收集器是Parallel Scavenge的老年代版本,这个收集器在jdk1.6后才提供
在此之前,由于Parallel Scavenge不能与cms搭配使用,只要年轻代使用了Parallel Scavenge收集器,老年代就只有Serial Old一种可选
由于serial old的单线程特点,导致无法利用多cpu服务器的性能优势
六、cms收集器(concurrent mark sweep)
cms收集器是为将垃圾回收时的停顿时间缩小到最短而开发的收集器
使用标记-清除算法
回收过程主要分为四步
初始标记、并发标记、重复标记、并发清除,其中,初始标记和重复标记依然需要stop the world
初始标记:标记所有与gc root能关联到的对象,速度很快
并发标记:并发的进行gc root tracing
重复标记:修正并发标记过程中,用户程序执行导致状态变化的对象
并发清除:并发的清除对象
注意:初始标记和重复标记需要时间较短,所以,即使需要stop the world也对性能影响不大
CPU敏感性:
cms收集器对cpu数量敏感,在并发阶段虽然不会停止用户线程,但会占用CPU资源,cms默认回收线程数时(cpu数量+3)/4,当cpu数量小于4个时,对用户线程的影响比较大,会导致在垃圾回收时用户线程执行速度忽然大幅下降,这种影响不可接受,为了应对这种情况,jvm提供了一种增量式并发收集器。原理是当进行并发回收时让用户线程和回收线程交替进行,减少gc线程的独占资源时间实践证明,这种增量式方式性能不是很好,已经不建议使用
浮动垃圾的处理:
由于在并发清除过程中用户线程依然执行并产生垃圾,此时cms已经无法对他们进行标记,只能等待下一次gc时再清除他们,这些垃圾称为浮动垃圾。正因如此,在执行gc对过程中依然要给用户线程留出足够的内存空间来使用,因此cms不会像其他垃圾收集器哪样等老年代完全被填满才开始进行gc,可以通过CMSInitiatingOccupancyFraction参数控制触发百分比,jdk1.6默认为92%。若cms在垃圾回收过程中无法满足用户线程内存需要,在出现Concurrent model failure,cms将启动备用方案,使用Serial Old对老年代进行一次回收
内存碎片:
由于使用标记-清除算法,在进行多次gc后会产生需要内存碎片,这将导致给大对象的分配带来困难,不得不处罚一次full gc。为解决这个问题,cms提供一个UseCmsCompactAtFullCollection开关,用于在fullgc时对老年代执行一次合并整理过程,整理过程无法并发。另外还提供一个CMSFullGCsBeforeCompaction参数来控制几次fullgc后执行一次整理,默认为0,即每次都整理。
七、G1收集器
G1收集器是当今收集器最新最前沿的成果,G1点开发者希望在不久的将来可以替代CMS。
特点:
1.并行与并发
G1能充分利用Cpu资源,在其他收集器需要需要停顿java线程的操作,G1依然可以利用并发的方式执行
2.分代收集
G1依然保留分代收集的概念,G1虽然可以独自处理新生代和老年代,但它用其他方式管理新创建对象和长时间存活对象,来获取最好的收集效果
3.空间整合
G1在局部看采用的复制算法,整理上看使用标记-整理算法,两种算法均能避免碎片的产生
4.可预测的停顿
G1在降低回收效率低同时还建立的可预测的停顿时间模型,能使使用者明确在M毫秒的时间段内回收时间不超过N毫秒
基本原理:
G1通过将整个堆分为若干个大小相等的区域Region,新生代和老年代已不是物理隔离,而都是一部分region的集合。
G1跟踪各个region的价值,在后台维护一个优先列表,保证在有限时间内将回收作用最大化。
G1将每个region的引用信息技术在一个Remembered set中,在gc枚举根节点时也枚举remembered set就不会有遗漏
执行过程:
初始标记、并发标记、最终标记、筛选回收
过程与cms很像,初始标记需要停顿线程但耗时很短,最终标记也需要停顿线程,但可并行之行。
最终标记作用与cms一样,只是他将对象的变化记录在remembered Set Log中,完成后将结果合并近remembered set中