JVM中关于GC参数配置如下:
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC(在发生GC时打印出堆信息)
这样配置以后,发生GC时输出的日志就类似于下面这种格式:
1、Heap before GC
发生GC前的堆信息
(1)par new generation total 1507328K, used 1507328K
年轻代,GC前总共容量1507328K,使用1507328K;这说明,年轻代空间已经完全使用完以后才发生GC。
(2)concurrent mark-sweep generation total 1048576K, used 13256K
老年代,GC前总共容量1048576K,使用13256K。
(3)concurrent-mark-sweep perm gen total 159324K, used 101267K
永久代,GC前总共容量159324K,使用101267K。
2、[GC34.095: [ParNew: 1507328K->65535K(1507328K), 0.1472690 secs] 1520584K->128190K(2555904K), 0.1474340 secs] [Times: user=0.28 sys=0.02, real=0.14 secs]
(1)发生了Minor GC(年轻代GC)
(2)GC使用的收集器是ParNew
(3)GC前年轻代使用大小为1507328K,GC后年轻代使用大小为65535K,年轻代总大小1507328K,GC时间0.1472690 secs
(4)GC前年轻代+老年代使用大小为1520584K,GC后年轻代+老年代使用大小为128190K,年轻代+老年代总大小为2555904K,GC总时间0.1474340 secs
3、Heap after GC
发生GC后的堆信息
(1)par new generation total 1507328K, used 65535K
年轻代,GC后总共容量1507328K,使用65535K;GC后年轻代使用容量大为降低。
(2)concurrent mark-sweep generation total 1048576K, used 62654K
老年代,GC后总共容量1048576K,使用62654K。GC后老年代的容量反而增加了不少,说明有好多对象从年轻代晋升到老年代了。
(3)concurrent-mark-sweep perm gen total 159324K, used 101267K
永久代,GC后总共容量159324K,使用101267K。GC后永久代大小没变。
下面看下老年代的GC:
老年代使用CMS收集器,发生GC时主要有以下几个步骤:
1、CMS-initial-mark: 62654K(1048576K)] 579016K(2555904K), 0.2322750 secs
初始标记,老年代已用空间62654K,总空间1048576K;年轻代+老年代已用空间579016K,总空间2555904K;标记时间0.2322750 secs;
初始标记阶段会Stop The World,此阶段标记的对象只是从root集最直接可达的对象。
2、CMS-concurrent-mark: 0.106/0.109 secs
此阶段是和应用线程并发执行的,主要作用是标记可达的对象;
此阶段会打印2条日志:CMS-concurrent-mark-start,CMS-concurrent-mark
3、CMS-concurrent-preclean: 0.014/0.015 secs
此阶段主要是进行一些预清理,因为标记和应用线程是并发执行的,因此会有些对象的状态在标记后会改变,此阶段正是解决这个问题,因为之后的Rescan阶段也会Stop The World,为了使暂停的时间尽可能的小,也需要preclean阶段先做一部分工作以节省时间;
此阶段会打印2条日志:CMS-concurrent-preclean-start,CMS-concurrent-preclean
4、CMS-concurrent-abortable-preclean: 4.915/5.016 secs
此阶段的目的是使CMS GC更加可控一些,作用也是执行一些预清理,以减少Rescan阶段造成应用暂停的时间;
此阶段涉及几个参数:
-XX:CMSMaxAbortablePrecleanTime:当abortable-preclean阶段执行达到这个时间时才会结束;
-XX:CMSScheduleRemarkEdenSizeThreshold(默认2m):控制abortable-preclean阶段什么时候开始执行,即当eden使用达到此值时,才会开始abortable-preclean阶段;
5、CMS-remark
重新标记阶段
此阶段会Stop The World,对对象进行重新扫描并标记;
YG occupancy: 881051 K (1507328 K)]:执行时年轻代的情况;
CMS-remark: 62654K(1048576K)] 943706K(2555904K), 0.4319280 secs:执行时老年代的情况;
此外,还打印出了弱引用处理、类卸载等过程的耗时;
6、CMS-concurrent-sweep: 0.043/0.045 secs
这个阶段进行并发的垃圾清理
7、CMS-concurrent-reset: 0.004/0.004 secs
这个阶段为下一次CMS GC重置相关数据结构