GC参数

串行收集器

  串行收集器(Serial),是一个相对比较老的回收器,但是它的效率在回收器中相对较好,并且比较稳定。他在进行垃圾回收的过程中,使得应用暂时被挂起,然后启用单条线程去做垃圾回收,所以在进行垃圾回收的过程中,可能会产生比较长的时间的停顿,可能对程序造成一定的影响。

  • 串行收集器相关参数
参数作用
-XX:+UseSerialGC 开启串行收集器,新生代,老年代都会使用串行回收,而新生代会使用复制算法进行回收,而老年代则使用标记压缩算法进行回收

  串行收集器运行流程入下:在GC时应用线程暂停,串行GC进行垃圾回收,回收结束之后,应用继续运行。

  我们看下面例子:

  这我的的代码所进行的几次GC信息,在第一次和第五次GC有进行新生代的GC,和老年代的GC,而其他的GC只进行了新生代的GC。

并行收集器

  • ParNew 收集器
    ParNew并行收集器,是一个新生代的收集器,使用parNew之后,新生代进行GC时就会并行,GC算法依旧是复制算法,但是老年代依旧会使用串行的方式进行回收。多线程垃圾回收,并不一定效率会高,如果是单核cpu,有可能性能还要比串行收集器差,但是它在多核的情况下性能会比较好,当然也要合理的配置线程的数量。
    使用 -XX:+UseParNewGC 参数可以开启 ParNew 新生代收集器
    我们在开启 ParNew 收集器之后,在打印 GC 日志时,会在新生代处有标记,如下:

ParNew收集器参数:

参数作用
-XX:+UseParNewGC 开启 ParNew 收集器,新生代使用并行收集,老年代使用串行收集
-XX:ParallelGCThreads 限制并行收集的线程数量
  • Parallel 收集器
    Parallel 收集器类似于 ParNew 收集器,新生代依旧使用复制算法,老年代还是使用标记压缩法,但是他是新生代和老年代垃圾回收的并行化收集器。
    我们在开启Parallel收集器之后日志会有以下的变化:

Parallel 收集器参数:

参数作用
-XX:+UseParallelGC 使用 Parallel 收集器,新生代并行,老年代串行
-XX:+UseParallelOldGC 使用 Parallel 收集器,新生代并行,老年代并行
-XX:MaxGCPauseMills 设置GC的最大停顿时间,单位为毫秒,GC会尽量保证回收时间不超过设定值
-XX:GCTimeRatio 设置垃圾收集时间的占比,默认为99,最大允许1%的时间做GC

  其中-XX:MaxGCPauseMills和-XX:GCTimeRatio两个参数相互矛盾,要想GC停顿的时间短,那么GC的次数就会增多,所占用整体的时间就会增加,但是如果GC次数过多,就会影响到系统的吞吐量(单位时间内CPU所分配给应用的时间越多,系统的吞吐量就越大),所以到底想要那部分的增强,就需要在实际业务场景下看系统需要哪方面增强。

  最后附上一张并行收集器的GC 进行回收时的图,以便于理解:

CMS 收集器

CMS(Concurrent Mark-Sweep)收集器,是一个老年代收集器,它使用的GC算法为标记清除法,但是他是一个并发的收集器,它与应用程序可以并发执行。它是一个以牺牲吞吐量为代价来获得最短回收停顿时间的垃圾回收器。对于要求服务器响应速度的应用上,这种垃圾回收器非常适合,目标是尽量减少应用的暂停时间,减少full gc发生的几率,利用和应用程序线程并发的垃圾回收线程来标记清除年老代。
CMS收集器因为时并发收集器,所以它的运行过程是比较复杂的,可以分为一下几个步骤:

  • 初始标记(单线程,通过根结点标记对象,速度快,但是会产生全局停顿)
  • 并发标记(和应用并发进行,标记所有对象,区分是否被引用)
  • 重新标记(在前面标记过程中存在并发操作,所以还会产生垃圾,此时会进行修正标记,但是也是会产生全局停顿)
  • 并发清除(根据标记结果,清理对象,和应用程序并发进行)

  并发标记时使用时的一些参数:

参数作用
-XX:+UseConcMarkSweepGC 开启使用cms收集器
-XX:CMSInitiatingOccupancyFraction 设置触发GC的阀值
-XX:+UseCMSCompactAtFullCollection full GC之后进行一次压缩整理,压缩整理时独占的,会引起停顿
-XX:+CMSFullGCsBeforeCompaction 设置进行几次Full GC后进行一次碎片整理
-XX:ParallelCMSThreads 设置CMS的线程数量,一般设置可用CUP的数量

CMS收集器的特点:

  • 尽可能降低停顿
  • 会影响整个系统的吞吐量和性能
  • 清除不彻底(因为在清除过程中,应用程序还在运行,还会产生新的垃圾)
  • 不可以在空间快满时清除(因为和系统应用并发执行,如果内存空间预留不够,则会引起concurrent mode failure如果出现错误,则会启用串行收集器应用挂起进行串行回收。)
  • 在标记清除之后会产生内存碎片(不连续的内存空间),还需要进行压缩整理,否则无法分配占用空间大的对象。

  下面为GC在使用CMS收集器时打出的日志:

CMS为什么不使用标记压缩算法呢?因为CMS收集器在收集过程中时并发的,而标记压缩在压缩整理过程会将内存位置进行移动,那么此时的应用程序就会出现问题,所以在CMS中使用标记清除法,只会去清除未被使用的对象。

-------------------- END ---------------------

 

最后附上作者的微信公众号地址和博客地址 

公众号:wuyouxin_gzh

 

Herrt灬凌夜:https://www.cnblogs.com/wuyx/

原文地址:https://www.cnblogs.com/wuyx/p/9671717.html