学习JVM原理-8.一个GC调优的实例

这个例子算是《深入理解Java虚拟机》第5章中某个例子的简写版。

1. 症状:系统启动比较慢,可能跟GC不力有关

2. 诊断:通过
打印GC日志,看看有没有什么不正常

  a.为了打印GC日志,系统启动时加上三个JVM参数:

    -XX:+PrintGCTimeStamps

    -XX:+PrintGCDetails

    -verbose:gc

  b.启动系统,得到GC日志,这时可以重点关注Full GC,因为Full GC的时间比Minor GC长的多:

16.400: [Full GC 16.400: [Tenured: 53K->8872K(87424K), 0.5714300 secs] 26375K->8872K(126720K), [Perm : 16384K->16384K(
16384K)], 0.5715650 secs] [Times: user=0.26 sys=0.01, real=0.58 secs]

20.159: [Full GC 20.159: [Tenured: 8872K->10445K(87424K), 0.3710940 secs] 18205K->10445K(126848K), [Perm : 20479K->20479K(
20480K)], 0.3711840 secs] [Times: user=0.27 sys=0.00, real=0.38 secs]

22.959: [Full GC 22.959: [Tenured: 10445K->11563K(87424K), 0.4423500 secs] 23865K->11563K(126848K), [Perm : 24575K->24575K(
24576K)],

0.4424400 secs] [Times: user=0.30 sys=0.00, real=0.44 secs]

26.140: [Full GC 26.140: [Tenured: 11563K->12442K(87424K), 0.7550570 secs] 24071K->12442K(126848K), [Perm : 28671K->28659K(
28672K)], 0.7551550 secs] [Times: user=0.42 sys=0.00, real=0.76 secs]

30.654: [Full GC 30.654: [Tenured: 12442K->14071K(87424K), 0.7421590 secs] 32731K->14071K(126848K), [Perm : 32767K->32767K(
32768K)], 0.7422500 secs] [Times: user=0.39 sys=0.01, real=0.74 secs]

看加粗的数字,你会发现Permenant Generation的总容量越来越大,也就是说由于它被塞满,导致JVM必须给它扩容,并触发GC

3.解决:为了解决这个问题,应该让Permenant Generation的初始容量一开始就比较大,免得老是扩容。一般可以直接把它固定为最大值,比如


-XX:PermSize=128m

-XX:MaxPermSize=128m

类似的事情还会发生在Tenured Generation和Young Generation上,也可以采用相应的“固定内存大小法”来解决.

4.另一种诊断办法: 如果上次GC的表现很差,而根据GC Details又看不出什么门道,则可以直接查看一下它的原因

   jstat -gccause
vmid

看一下输出结果中的"LGCC"列,找出具体原因,然后进行处理

 举例来说,如果这列的值是System.gc(),则表明代码里有人显示地调用了GC. 如果觉得不再需要它了,可以用 -XX:+DisableExplicitGC来屏蔽它

Leave a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.