GC收集器理解

Posted jemb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GC收集器理解相关的知识,希望对你有一定的参考价值。

GC的收集器种类:

技术图片

 

 收集器存在连线的说明他们可以配合使用。

 

新生代垃圾收集器

1.串行GC(serial)垃圾回收器

  单线程收集器,必须暂停所有的工作线程直到结束:

技术图片

 

最古老,稳定效率高的垃圾回收器

对应的JVM参数是: -XX:+UseSerialGC

开启后会使用:Serial(Young区用) + Serial(Old区用)的收集器组合,表示新生代,老年代都会使用串行的垃圾回收器,

新生代使用复制算法,老年代使用标志-整理算法

参数示例:  -Xms10m  -Xmx10m  -XX:PrintGCDetails  -XX:UseSerialGC   

 

 

2.并行GC(ParNew)收集器

使用多线程进行垃圾回收,在垃圾回收时,会 STW暂停其他所有工作线程直到他结束。

 

 技术图片

 

ParNew收集器就是Serial收集器的新生代的并行多线程版本。最常见的是

配合老年代的CMS GC工作。其余行为和Serial行为一样,同样需要暂停所有线程。

开启后:新生代使用并行垃圾回收,老年代使用串行垃圾回收。

JVM参数:-XX:+UseParNewGC 

JDK8 的默认垃圾回收器,ParNew+Serial这条线已经不被使用,官方已经说这样不好。

备注: -XX:ParallelGCThreads  限制线程数,默认启动和CPU数目相同的线程数

 

 3.Parallel Scavenge(Parallel GC)

技术图片

 

关注:(适用与计算型场景,无需考虑停顿时间,直接开起多个线程)

可控吞吐量 = (运行代码时间/ 运行代码垃圾手机时间) 

程序运行100分钟,垃圾收集器1分钟,吞吐量为99%

自适应调节策略:根据当前系统的运行情况收集性能,监控信息,动态调整这些参数提供合适的停顿时间(-XX:MaxGCPauseMillis)和吞吐量

JVM参数:-XX:+UseParallelGC

    -XX:ParallelGCThreads =  数字N,N表示启动多少个GC线程

    cpu线程数  >  8              N = 5/8 

    cpu线程数  <  8             N = 实际cpu线程数

 

老年代垃圾收集器:

1.SerialOld(单线程老年代)

作用: 作为老年代版本CMS垃圾收集器的 后备收集器

 

2.CMS(并发标记清除)

Concurret Mark Sweep:是一种以获取最短回收停顿时间为目标的收集器。

适合应用在互联网或B/S系统的服务器上,这类应用重视服务器的相应速度,希望系统停顿时间最短。

虽然JDk后的G1出现了对停顿时间可控的功能,但是对于小于32G的场景,CMS还是中小型公司的首选。

 

并发收集低停顿,并发指的是与用户线程一起执行。

CMS必须在老年代堆内存耗尽前,完成GC回收。否则将触发担保机制,使用串行回收,将造成更大的停顿时间。技术图片

 

 

 

 

 

JVM参数:-XX:+UseConcMarkSweepGC 开启参数,会自动将 -XX:+UserParNewGC打开、

开启参数后:;使用ParNew(Young)+CMS(Old)+SerialOld(CMS出错启用)

 

CMS垃圾回收四大阶段

初始标记(initial mark): 标记一下GC Roots能直接引用的对象罢了,速度很快,需要暂停所有工作线程,但是影响不大,速度很快

并发标记(concurrent mark):垃圾回收线程对已有对象进行GC Roots追踪。同时这个过程还会创建新的对象,也可能让部分存活的对象失去引用。

重新标记(remark):因为第二阶段,一边标记存活对象和垃圾对象,一边系统不停的创建新的对象,让老对象变成垃圾。第二阶段后,肯定有很多存活对象和垃圾对象,是第二阶段没有标记出来的。所以第三阶段,需要让系统停下来,对第二阶段的垃圾对象进行处理。由于是对第二阶段少数对象进行标记,所以速度还是很快的。

并发清理(concurrent sweep):清除GCRoot 不可达的对象,和用户线程一起工作

总体来看:CMS的内存回收线程和用户线程一起并发执行

 

GCROOT?

垃圾:内存中不再被使用到的空间就是垃圾,判断一个对象是否能够被回收,枚举根节点可达性算法,必须是一组活跃的引用

GCRoots对象:

1.虚拟机栈(栈帧的局部变量所引用的对象)

2.方法区类静态变量引用的对象的对象

3.方法区中常量引用的对象

4.本地方法栈(JNI Native)中引用的对象

 

 

CMS优缺点?

优点:并发收集低停顿

缺点:

1.CMS在收集时与应用程序一起运行会增加堆内存的占用,CMS必须在老年代的堆内存耗尽前完成垃圾回收,否则回收失败,会触发担保机制串行化的老年代垃圾收集器会造成较大的停顿时间

2.采用标记清除算法,无法整理空间碎片,老年代空间会随着应用时间变长,逐步被耗尽,最后不得不使用担保机制进行堆内存的压缩。

CMS提供了参数: -XX:CMSFullGCsBeforeCompaction(默认为0,即每次都进行内存的整理)来指定多少次CMS垃圾收集之后,进行一次压缩的FullGC

 

 

G1

面向服务端引用收集器,应用在多处理器和大容量内存的环境,实现高吞吐量的同时,减少停顿时间。

 

特点:

1.不会产生碎片 (G1中region的一部分包含老年代,GQ收集器通过将对象从一个区域复制到另一个区域,完成清理的工作。在正常的处理过程中,G1完成了堆内存的压缩,这样就不会有CMS的碎片化问题)

2.用户可以指定期望停顿的时间

3.充分利用多核Cou,多核环境的优势,尽量缩短STW, G1整体采用标记-清理,局部使用复制短发,宏观上不区分新生代,老年代,微观上保留了新生代和老年代的区分

 

主要改变Eden,Survivor和tenured 等内存区域,不再时连续的了,而是变成一个个大小一样的region 1-32M,最多能设置2048个区域,

最大32M*2048 = 64G,一个region可能是Eden,Survivor和Tenured区域

 

 

ZGC(10毫秒级别)

特点:

1.着色指针:一个指针64位,寻址使用42位,剩下22位保存着色信息,标记

2.读屏障:解决GC线程和应用线程并发修改对象状态的问题,而不是通过STW实现全局的锁定

3.并发处理:

4,.基于region,动态决定大小,对大对象进行分配

 

 

 

 

 

以上是关于GC收集器理解的主要内容,如果未能解决你的问题,请参考以下文章

理解GC日志

理解GC日志

JVM理论:(二/4)理解GC日志垃圾收集器参数总结

深入理解java虚拟机GC垃圾回收-经典垃圾收集器

垃圾收集器与内存分配策略之篇三:理解GC日志和垃圾收集器参数总结

深入理解java虚拟机GC垃圾回收-垃圾收集算法