Skip to main content

GC算法之CMS总结

Submitted by taotao on Sun, 08/25/2019 - 08:37

概述

在之前的一篇文章,解决JVM内存泄漏的问题中,涉及到了GC的问题,为了把GC切底弄清楚,花了不到2个星期的业余时间,把这一块的知识复习了一下,所以现在开始对GC中的CMS算法做下总结,原来计划是上个周周末写这篇文章的,但是因为有其他事情,总是不断打断这个计划,于是一直拖到了8月份的下旬了。

JVM的垃圾回收算法有很类别,比如:并行垃圾回收、stop-the-world、并发垃圾回收,垃圾回收器可以是这个类别中的的一种或者多种的组合,因为我经常使用的是CMS垃圾回收器,因此我这里详细介绍CSM垃圾回收算法。阅读完本文你会了解如下的内容:

  1. 什么是CMS,它是为了解决什么问题而出现的?
  2. CMS是如何工作的?
  3. CMS使用过程中会经常遇到什么问题,我们需要如何避免这种问题?

 

什么是CMS?它是为解决什么问题而出现的?

CMS的全称为Concurrent Mark Sweep,中文直译为并发标记删除,这个GC是在JDK的7之后才引入的,为什么要引入CMS? 目的是为了解决GC执行时间过长而导致的应用长时间的停顿的问题。那你会问其他的垃圾回收器会导致应用有较长的停顿时间吗? 回答是肯定的,比如:

  • 并发垃圾回收器,每一次GC它都会stop-the-world,而且是新生代和老年代一起执行GC,这样就导致应用的线程都会停止执行,等待GC执行完毕之后,应用的线程才能够执行,因为在老年代的GC中还需要执行空间压缩,对象转移等操作,就导致了每一次GC的时间都会很长;
  • 串行垃圾回收器:每次GC只有一个线程在执行,而且每次执行的时候,应用的线程都需要停止执行。因为只有一个线程执行垃圾回收,这就导致了应用有更长的停顿时间。

如果我们的应用是批处理类型的,在单位时间内追求的是吞吐量,那么并行垃圾回收器可以满足需求,如果我们的应用是客户端类型的,串行垃圾回收器能够满足需求,但是如果我的应用的实时性要求比较高,对于长时间的停顿是无法接受的,那么这两种垃圾收集器就都不能满足需求了。在此背景下,于是就诞生了CMS垃圾回收器。它是如何可以满足低延迟的需求的,下面详细解释。 

CMS是如何工作的?

 CMS的执行依次遵循如下几个阶段:

  • 初始标记:在这个阶段,应用会stop-the-world,GC线程会从GC Root出发找出可以被Root对象引用到的对象,这些对象被称为活对象;
  • 并发标记:和初始标记做一样的事情,应用也会stop-the-world;
  • 重新标记:在这个阶段里,做的事情和初始阶段是一样的,主要是避免有遗漏的对象没有被标记;
  • 标记清除: 依次从内存的初始位置开始寻找那些没有被标记的对象,进行清除;

那为什么CMS能够满足应用对于低延迟需求?

  1. 因为CMS的老年代GC和新生代的GC可以彼此独立进行,如果老年代的GC在执行的时候,发现有新生代的GC要执行,就会停下来,让新生代的GC优先执行,这样应用的线程只需要等待新生代的GC完成后就会恢复执行,不再需要等待老年代的GC执行完成,并行垃圾回收算法里,应用的线程需要等待新生代和老年代GC都执行完成之后,应用的线程才能恢复执行;
  2. 初始标记、并发标记都会导致应用停顿,但是这个时间是很短暂的;
  3. 在标记清除阶段,CMS是和应用的线程并发执行的,因此应用可以继续执行,不会受到gc的影响;

CMS的垃圾回收器存在的问题以及如何避免类似的问题

  • 如果我们新对象生成的速度大于旧对象被回收的速度,那么就会导致内存益处的问题
  • 如果新晋升到老年代的对象太大,内存中没有足够大的连续的空间,就会导致CMS执行一次full gc,这样就导致了应用的性能下降
  • 上述两个问题都不可预测

这几个问题,我们一方面可以通过增加JVM的内存大小,避免内存不够用的问题,另一个方面,可以通过设置如下参数:

-XX: +CMSInitiatingOccupancyFraction

调整何时触发CMS的执行,该值默认是70%,然后设置如下参数,用于打开JVM的日志输出:

-XX:+PrintGC

这样我们就可以观察有full gc的时候,当前的触发cms执行是在什么比例下执行的,通过反复调整,看在什么百分比之下,full gc的频次是最低的。

总结

本文为你介绍了Java中几种常见的GC算法,包括并行、stop-the-world、并发,因为常用的是CMS垃圾回收算法,因此详细介绍了CMS是因为什么问题而被引入的,以及它和其他几种垃圾回收器的区别,另外介绍了CMS垃圾回收器的工作机制,以及它面临的问题,本文给出了这个问题的解决方案,这个方案是需要不断的进行观察,调试,找到一个最优的配置,以此降低full gc的频次。 

 

Add new comment

Plain text

  • No HTML tags allowed.
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.