【Java】CMS 垃圾回收 GC

CMS

简介:
全称是Concurrent Mark Sweep,年轻代使用了STW并行复制算法,老年代采用了并发的标记-清除算法,主要目的是减少老年代垃圾回收的暂停时间。缺点是采用了清除算法,所以会产生碎片垃圾。若想启动,使用参数“-XX:+UseConcMarkSweepGC”,该算法已经在jdk7及以后的版本中废弃了,建议使用G1,但是cms对于理解G1等更高级的垃圾回收器很有帮助。

阶段:
1.InitialMarking:
需要STW,主要标记直接可达对象,包括GCROOTS可达和年轻代可达。

2.Marking:
该阶段GC线程与用户线程并发执行,从第一步的对象开始标记可达对象。

3.PreCleaning:
该阶段是非必须的,默认是开启的,可以使用参数“XX:-CMSPrecleaningEnabled”关闭。为什么需要这个阶段?并发标记阶段是与用户线程同时执行的,标记阶段引用可能发生改变,进而产生漏标的情况。
比如:新对象晋升老年代,老年代对象引用改变,新的对象的分配等。这些操作都可以基于卡表和写入屏障记录下来,所以这个阶段就根据卡表信息重新标记这些有改变对象。

4.AbortablePreclean:
该阶段的作用我目前没有找到特别好的解释。但是大致是:
首先3,4都是为了下面的第五步也即ReMark阶段做准备。由于3,4是并发执行的,所以无论3,4怎么处理,都不可能完美标记所有存活对象,所以5一定是STW的,那么5就需要重新遍历GCROOT和新生代对象,这里的4即AbortablePreclean就是为了减少5遍历新生代对象的时间的。
https://blogs.oracle.com/poonam/understanding-cms-gc-logs
那么如何做到这一点?
一个是希望通过在该阶段执行时,让新生代Eden区有一定数量的对象,从而出发一次YGC。
第二个就是直接标记从新生代到老年代的对象。

5.Remark:
是STW的,重新标记。可能需要较长时间,取决于3,4的效果。该阶段可以通过参数“-XX:+CMSScavengeBeforeRemark”参数强制执行一次YGC,默认不开启。不过由于4可能发生一次YGC,如果5又强制发生一次,自然会使停顿时间更久。

6.Concurrent Sweep:
并发清除。

7.Concurrent Reset:
状态清除。

 

最后附上一段日志:

$ tail -f gc.log
Java HotSpot(TM) 64-Bit Server VM (25.161-b12) for windows-amd64 JRE (1.8.0_161-b12), built on Dec 19 2017 17:52:25 by "java_re" with MS VC++ 10.0 (VS2010)
Memory: 4k page, physical 16638568k(7912876k free), swap 34464360k(22071744k free)
CommandLine flags: -XX:InitialHeapSize=10485760 -XX:MaxHeapSize=10485760 -XX:MaxNewSize=3497984 -XX:MaxTenuringThreshold=6 -XX:NewSize=3497984 -XX:OldPLABSize=16 -XX:OldSize=6987776 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:-UseLargePagesIndividualAllocation -XX:+UseParNewGC
0.183: [GC (Allocation Failure) 0.183: [ParNew: 2752K->320K(3072K), 0.0035948 secs] 2752K->1069K(9920K), 0.0037078 secs] [Times: user=0.02 sys=0.02, real=0.00 secs]
0.242: [GC (Allocation Failure) 0.242: [ParNew: 3072K->320K(3072K), 0.0015297 secs] 3821K->1830K(9920K), 0.0015642 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
1.251: [GC (Allocation Failure) 1.251: [ParNew: 2998K->278K(3072K), 0.0011781 secs] 4508K->2787K(9920K), 0.0012103 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
2.253: [GC (Allocation Failure) 2.253: [ParNew: 3004K->74K(3072K), 0.0020237 secs] 5513K->3755K(9920K), 0.0020603 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
2.256: [GC (Allocation Failure) 2.256: [ParNew: 1695K->18K(3072K), 0.0011042 secs] 5376K->4506K(9920K), 0.0011313 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
2.261: [GC (CMS Initial Mark) [1 CMS-initial-mark: 4488K(6848K)] 5731K(9920K), 0.0027247 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
2.264: [CMS-concurrent-mark-start]
2.274: [CMS-concurrent-mark: 0.010/0.010 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
2.275: [CMS-concurrent-preclean-start]
2.275: [CMS-concurrent-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
2.275: [GC (CMS Final Remark) [YG occupancy: 1243 K (3072 K)]2.275: [Rescan (parallel) , 0.0012716 secs]2.276: [weak refs processing, 0.0000643 secs]2.276: [class unloading, 0.0003765 secs]2.277: [scrub symbol table, 0.0003918 secs]2.277: [scrub string table, 0.0001001 secs][1 CMS-remark: 4488K(6848K)] 5731K(9920K), 0.0022851 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
2.277: [CMS-concurrent-sweep-start]
2.278: [CMS-concurrent-sweep: 0.001/0.001 secs] [Times: user=0.05 sys=0.00, real=0.00 secs]
2.278: [CMS-concurrent-reset-start]
2.278: [CMS-concurrent-reset: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
3.257: [GC (Allocation Failure) 3.257: [ParNew: 2419K->296K(3072K), 0.0029963 secs] 4557K->3996K(9920K), 0.0030314 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
3.261: [GC (CMS Initial Mark) [1 CMS-initial-mark: 3700K(6848K)] 4413K(9920K), 0.0006313 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
3.262: [CMS-concurrent-mark-start]
3.263: [CMS-concurrent-mark: 0.001/0.001 secs] [Times: user=0.05 sys=0.00, real=0.00 secs]
3.263: [CMS-concurrent-preclean-start]
3.263: [CMS-concurrent-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
3.263: [CMS-concurrent-abortable-preclean-start]
4.262: [GC (Allocation Failure) 4.262: [ParNew (promotion failed): 2915K->2619K(3072K), 0.0010724 secs]4.263: [CMS4.263: [CMS-concurrent-abortable-preclean: 0.002/1.001 secs] [Times: user=0.00 sys=0.00, real=1.00 secs]
 (concurrent mode failure): 3704K->2930K(6848K), 0.0285812 secs] 6615K->2930K(9920K), [Metaspace: 4603K->4603K(1056768K)], 0.0297131 secs] [Times: user=0.00 sys=0.00, real=0.03 secs]
4.292: [GC (Allocation Failure) 4.293: [ParNew: 2037K->2K(3072K), 0.0012418 secs] 4968K->4134K(9920K), 0.0012740 secs] [Times: user=0.02 sys=0.00, real=0.00 secs]
4.294: [GC (CMS Initial Mark) [1 CMS-initial-mark: 4132K(6848K)] 6771K(9920K), 0.0019858 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
4.296: [CMS-concurrent-mark-start]
4.297: [CMS-concurrent-mark: 0.001/0.001 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
4.298: [CMS-concurrent-preclean-start]
4.298: [CMS-concurrent-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
4.298: [CMS-concurrent-abortable-preclean-start]
5.296: [GC (Allocation Failure) 5.296: [ParNew (promotion failed): 2692K->2690K(3072K), 0.0015862 secs]5.298: [CMS5.298: [CMS-concurrent-abortable-preclean: 0.001/1.000 secs] [Times: user=0.00 sys=0.00, real=1.00 secs]
 (concurrent mode failure): 4134K->3809K(6848K), 0.0047763 secs] 6825K->3809K(9920K), [Metaspace: 4603K->4603K(1056768K)], 0.0064186 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
6.304: [GC (Allocation Failure) 6.304: [ParNew: 2681K->84K(3072K), 0.0011646 secs] 6490K->4286K(9920K), 0.0012139 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
6.306: [GC (Allocation Failure) 6.306: [ParNew: 1532K->2K(3072K), 0.0012722 secs]6.308: [CMS: 5011K->4949K(6848K), 0.0054021 secs] 5734K->4949K(9920K), [Metaspace: 4604K->4604K(1056768K)], 0.0067308 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]
6.313: [Full GC (Allocation Failure) 6.313: [CMS: 4949K->4949K(6848K), 0.0033337 secs] 4949K->4949K(9920K), [Metaspace: 4597K->4597K(1056768K)], 0.0033568 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
6.317: [GC (CMS Initial Mark) [1 CMS-initial-mark: 4949K(6848K)] 4949K(9920K), 0.0006749 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
6.318: [CMS-concurrent-mark-start]
Heap
 par new generation   total 3072K, used 109K [0x00000000ff600000, 0x00000000ff950000, 0x00000000ff950000)
  eden space 2752K,   3% used [0x00000000ff600000, 0x00000000ff61b740, 0x00000000ff8b0000)
  from space 320K,   0% used [0x00000000ff900000, 0x00000000ff900000, 0x00000000ff950000)
  to   space 320K,   0% used [0x00000000ff8b0000, 0x00000000ff8b0000, 0x00000000ff900000)
 concurrent mark-sweep generation total 6848K, used 4949K [0x00000000ff950000, 0x0000000100000000, 0x0000000100000000)
 Metaspace       used 4630K, capacity 4748K, committed 4992K, reserved 1056768K
  class space    used 519K, capacity 564K, committed 640K, reserved 1048576K

关于concurrent mode failure:

由于cms老年代是并发收集的,有可能导致还没收集完就有大量对象需要放入,然后空间不够的情况,就会触发concurrent mode failure。大量对象可能来自于与老年代也可能来自于年轻代,年轻代survivor区没有足够的空间容纳存活对象,将会放入老年代。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值