下面的gc log中的full gc是怎么触发的,理解不了,请大神看看~
2015-02-03T14:40:12.029+0800: 470.095: [GC [PSYoungGen: 1271672K->13218K(3940864K)] 1374109K->115656K(8135168K), 0.0061610 secs] [Times: user=0.05 sys=0.00, real=0.00 secs]
2015-02-03T14:40:12.036+0800: 470.101: [Full GC [PSYoungGen: 13218K->0K(3940864K)] [ParOldGen: 102437K->98542K(4194304K)] 115656K->98542K(8135168K) [PSPermGen: 64633K->64632K(262144K)], 0.3928440 secs] [Times: user=3.18 sys=0.02, real=0.40 secs]
2015-02-03T14:43:12.622+0800: 650.688: [GC [PSYoungGen: 2750752K->24677K(3932160K)] 2849294K->123219K(8126464K), 0.0274110 secs] [Times: user=0.06 sys=0.10, real=0.03 secs]
2015-02-03T14:43:12.650+0800: 650.715: [Full GC [PSYoungGen: 24677K->0K(3932160K)] [ParOldGen: 98542K->108727K(4194304K)] 123219K->108727K(8126464K) [PSPermGen: 65137K->65128K(262144K)], 0.4234160 secs] [Times: user=3.40 sys=0.03, real=0.42 secs]
2015-02-03T14:43:27.212+0800: 665.277: [GC [PSYoungGen: 828133K->12061K(3961344K)] 936860K->120788K(8155648K), 0.0092620 secs] [Times: user=0.05 sys=0.02, real=0.01 secs]
2015-02-03T14:43:27.221+0800: 665.287: [Full GC [PSYoungGen: 12061K->0K(3961344K)] [ParOldGen: 108727K->101742K(4194304K)] 120788K->101742K(8155648K) [PSPermGen: 65191K->65191K(262144K)], 0.2733550 secs] [Times: user=2.09 sys=0.01, real=0.27 secs]
从日志可以看出一些规律来,每次做完一次young gc会立马做一次full gc(时间几乎一致),此时young 区大小会变为0(开始大小和上一次young gc完的大小是一致的)
jdk版本为 1.7.0_55
JVM参数
-Xmx8192m -Xms8192m -XX:NewSize=4096m -XX:MaxNewSize=4096m -XX:SurvivorRatio=4 -XX:MaxPermSize=256m -XX:PermSize=256m
是不是有参数不生效。jps -v 看看
4096*1024*(1+4)/(1+1+4)=3495253K
3940864K 与3961344K。。。
在分析这段GC日志之前,需要先简单介绍一下垃圾回收机制。
JVM堆内存分为新生代和老年代,其中新生代又分为一个较大的 Eden 区和两个较小的 Survivor 区。在进行垃圾回收时,JVM会优先清理年轻代(Eden和Survivor)中的无用对象,即 Young GC。而在 Old GC 时,则会对老年代及持久代中的无用对象进行清理。
那么来解释一下这些GC日志:
第一段GC日志是Young GC日志,其中 PSYoungGen 表示新生代使用的是 Parallel Scavenge(并行清理)算法,日志中记录了young gen从1271672K减少到13218K再增加至3940864K的过程,young gc总共耗时0.0061610秒。
接着的第二段GC日志是Full GC 日志,记录了在young gc 后,Old区使用的Parallel old压缩算法,ParOldGen在该次GC后减少了103204K,但是此次full gc的时间cost较高,达到了0.39秒。
第三段GC日志继续记录了一次Young GC 日志,young gc所需的时间比第一次略长一点。
接着的第四段GC日志又是一次Full GC日志,可以看到在young gc阶段,Eden区大小减少到了0。跟第二段差不多,此次full gc的时间cost 较高,达到了0.4234160秒。
最后一段GC日志同样记录了一次Young GC 日志和一次Full GC 日志,young gc的时间相比较前面有所变化,而本次full gc的时间只有0.2733550秒,因此可以得出结论:full gc 频繁发生主要是由于应用程序使用了大量堆内存,触发了full gc中老生代的回收,且此时老年代中无法找到足够的连续空间进行垃圾回收,因此需要花费较高的时间去压缩内存空间。