之前的文章介绍过了CMS垃圾回收器的工作原理,CMS是使用标记-清理算法去垃圾回收的。其中四个主要的流程分别是初始标记、并发标记、重新标记、并发清理。
- 并发消耗CPU资源
其中的并发标记和并发清理是工作线程和垃圾回收线程并发工作,这样在需要STW的时间内不会让整个系统不可用。但是在并发标记阶段,需要根据GC Roots标记出大量的存活对象,而在并发清理阶段,则需要将垃圾对象从各种随机内存位置删掉,这两个阶段都非常消耗性能,所以垃圾回收线程会占用一部分的CPU资源,导致系统的执行效率降低。
CMS默认的回收线程数是 (CPU个数+3)/4,当在CPU核数较多的时候,对系统性能的影响并不是特别大。但是如果是CPU核数较少,例如双核的时候,就会占用一个CPU去处理垃圾回收,系统的CPU资源直接降低50%,这就严重影响了效率。
因为现在CPU的核数越来越多,所以这种场景基本不会对系统造成很大的影响,可以忽略不计。
- Concurrent Mode Failure问题
并发清理阶段,工作线程和垃圾回收线程并发工作的时候,此时工作线程会不断产生新的垃圾,但是垃圾回收线程并不会去处理这些新生成的垃圾对象,需要等到下次垃圾回收的时候才会去处理,这些垃圾对象称之为:浮动垃圾 。因为有这些浮动垃圾的存在,所以老年代不能在100%使用的时候才去进行垃圾回收,否则就放不下这些浮动垃圾了。有一个参数是“-XX:CMSInitiatingOccupancyFraction”,这个参数在jdk1.6里面默认是92%,意思是老年代使用了92%的空间就会执行垃圾回收了。但是