理解CMS收集器
- CMS收集器在新生代垃圾回收时,所有应用线程都会暂停
- CMS收集器在老年代的垃圾处理上启动一个并发的线程进行回收,因此老年代的垃圾回收不会暂停应用线程,同时需要更高的CPU资源
-
由于CMS在老年代的垃圾处理是使用并发线程,没有对老年代进行压缩操作,堆中过度碎片化无法找到连续的空间分配给对象时或者无法获得任务所需的CPU资源时,会发起Full GC,暂停应用,使用单线程回收,整理压缩老年代。
CMS垃圾回收 - Minor GC.png
CMS 收集器的新生代垃圾收集与Throughput 收集器的新生代垃圾收集是类似的:对象从Eden 空间移动到Survivor 空间,或者移动到老年代空间。
CMS垃圾回收 - CMS周期.png
JVM会根据堆的使用情况启动并发回收,当堆的占用达到某个程度时,启动后台线程扫描堆回收无用的对象,老年代在CMS周期后如上图所示,由于没有压缩操作,空闲空间是非连续的,新生代垃圾收集后从Eden移到老年代时,会尝试使用空闲空间来保存对象。
CMS中会出现的耗时原因
- concurrent mode failure 并发模式失效
当新生代发生垃圾回收,同时老年代又没有足够的空间容纳晋升的对象时,CMS 垃圾回收就会退化成Full GC。此时所有应用线程都会暂停,老年代中所有的无效对象都会被回收,这个操作时单线程的,因而耗时会非常长。 - promotion failed 晋升失败
由于并发线程不会对老年代进行压缩操作,会出现老年代虽然有空闲空间,但这个空闲空间不是连续的,无法容纳从新生代晋升过来的对象,这是将会暂停应用线程,对老年代空间进行整理和压缩,由于此时是对整个堆进行整理,时间甚至比遭遇并发模式失效的时间还长的多,因为发生并发模式失效时,CMS收集器只需要回收堆内无用的对象。这时的堆就像刚由Throughput 收集器做完Full GC 一样:新生代空间完全空闲,老年代空间也已经整理过。
网友评论