论坛首页 Java企业应用论坛

为何主动设置Xmx为3G了,老生代已经99%了,JVM内存还不会自动扩容,导致FullGC非常频繁,从top命令上看内存只用到1g

浏览 11705 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-12-22  
JVM
为何主动设置Xmx为3G了,老生代已经99%了,JVM内存还不会自动扩容,导致FullGC非常频繁,从top命令上看内存只用到1g

如果改为-Xms3072m -Xmx3072m 一开始就直接分配3g的话,就没这个问题
但如果-Xms256m -Xmx3072m,问题就出现,FullGC非常频繁

查看了这2个参数也是默认的:
MinHeapFreeRatio 40
MaxHeapFreeRatio 70

环境信息如下:
操作系统:
Linux linux-wgvb 2.6.16.60-0.54.5-smp #1 SMP Fri Sep 4 01:28:03 UTC 2009 x86_64 x86_64 x86_64 GNU/Linux

JDK版本:
java version "1.6.0_32"
Java(TM) SE Runtime Environment (build 1.6.0_32-b05)
Java HotSpot(TM) 64-Bit Server VM (build 20.7-b02, mixed mode)

JVM内存参数:
-Xms256m -Xmx3072m  -XX:+UseParallelOldGC -XX:MaxGCPauseMillis=1000 -XX:ParallelGCThreads=5 -Xrs -XX:PermSize=64m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError

FullGC非常频繁:
@linux> ./jstat -gcutil 18261 1000 500
  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT  
  0.00  64.67   7.04  99.53  71.89  18293  510.574  1167 1616.594 2127.168
91.78   7.91 100.00  99.53  72.00  18299  510.821  1167 1616.594 2127.415
77.49   0.00   0.00  99.99  72.00  18300  510.947  1168 1616.594 2127.541
  0.00  99.83  25.71  99.49  71.72  18305  511.178  1168 1617.915 2129.093
24.27   0.00  21.74  99.67  71.73  18310  511.342  1168 1617.915 2129.256
28.57   0.00   0.00  99.83  71.73  18314  511.427  1169 1617.915 2129.342
  0.00  29.29   0.00  99.56  71.82  18317  511.465  1169 1618.919 2130.384
  0.00  78.85  54.96  99.56  72.05  18326  511.777  1169 1618.919 2130.696
64.52   0.00   0.00  99.99  72.05  18328  511.920  1170 1618.919 2130.839
  0.00  99.26   0.00  99.88  71.71  18333  512.079  1171 1620.014 2132.093
  4.86   0.00   0.00  99.95  71.76  18338  512.255  1172 1620.957 2133.211
80.98   0.00   0.00  99.69  71.83  18350  512.453  1172 1621.906 2134.359
  0.00  64.48   0.00  99.85  71.83  18355  512.677  1173 1621.906 2134.583
  0.00  99.80   0.00  99.93  71.71  18359  512.876  1174 1623.264 2136.139
  0.06   0.04 100.00  99.55  71.71  18360  512.876  1174 1624.193 2137.069
60.35   0.00   0.00  99.90  71.77  18376  513.429  1175 1624.193 2137.622
60.35   0.00   0.00  99.90  71.77  18376  513.429  1175 1624.193 2137.622
89.86   0.00   0.00  99.83  71.78  18384  513.839  1176 1625.476 2139.315
89.86   0.00   0.00  99.83  71.78  18384  513.839  1176 1625.476 2139.315
  0.00  39.17  64.41  99.60  71.78  18394  514.202  1176 1626.880 2141.082
99.93   0.00   0.00  99.82  71.78  18396  514.326  1177 1626.880 2141.206
  0.00  64.68   0.00  99.61  71.72  18401  514.409  1177 1627.945 2142.354

Top命令查看进程只用了1g内存,JVM没有自动扩容到Xmx:
PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                                                                      
18261 ouser   15   0 4353m 1.0g  52m S  325  3.2 271:25.52 java     

   发表时间:2013-01-21  
1.由JVM的Heap设置及GC日志可以看出来,频繁发生FullGC是很正常的。理由是,由于新生代没有足够内存可分配了(E为100%),故在进行Minor GC时,需要将一些对象进化到年老代,但是年老代又没有足够的空间(O为99.99%),这时触发FullGC。

  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT  
  0.00  64.67   7.04  99.53  71.89  18293  510.574  1167 1616.594 2127.168
91.78   7.91 100.00  99.53  72.00  18299  510.821  1167 1616.594 2127.415
77.49   0.00   0.00  99.99  72.00  18300  510.947  1168 1616.594 2127.541

2.当设置了-Xms256m -Xmx3072m时,我们计算可知,256/3*1024≈0.08 远小于0.7,而此时进行FullGC后,老生代的内存是够用的,故不会进行扩张(因为每次FullGC后都老生代都没有超过100%)。

3.为了进一步确认你的问题,你可以将heap的dump打印出来,请使用jmap -heap <pid>命令.

4.就你的环境及GC日志推测,推荐一个配置,请参考:
-server -Xss256k -Xms3g -Xmx3g -Xmn1g -XX:PermSize=128m -XX:MaxPermSize=128m -XX:+UseConcMarkSweepGC

环境信息如下:
操作系统:
Linux linux-wgvb 2.6.16.60-0.54.5-smp #1 SMP Fri Sep 4 01:28:03 UTC 2009 x86_64 x86_64 x86_64 GNU/Linux

JDK版本:
java version "1.6.0_32"
Java(TM) SE Runtime Environment (build 1.6.0_32-b05)
Java HotSpot(TM) 64-Bit Server VM (build 20.7-b02, mixed mode)
0 请登录后投票
   发表时间:2013-01-21  
dinstone 写道
1.由JVM的Heap设置及GC日志可以看出来,频繁发生FullGC是很正常的。理由是,由于新生代没有足够内存可分配了(E为100%),故在进行Minor GC时,需要将一些对象进化到年老代,但是年老代又没有足够的空间(O为99.99%),这时触发FullGC。

  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT  
  0.00  64.67   7.04  99.53  71.89  18293  510.574  1167 1616.594 2127.168
91.78   7.91 100.00  99.53  72.00  18299  510.821  1167 1616.594 2127.415
77.49   0.00   0.00  99.99  72.00  18300  510.947  1168 1616.594 2127.541

2.当设置了-Xms256m -Xmx3072m时,我们计算可知,256/3*1024≈0.08 远小于0.7,而此时进行FullGC后,老生代的内存是够用的,故不会进行扩张(因为每次FullGC后都老生代都没有超过100%)。

3.为了进一步确认你的问题,你可以将heap的dump打印出来,请使用jmap -heap <pid>命令.

4.就你的环境及GC日志推测,推荐一个配置,请参考:
-server -Xss256k -Xms3g -Xmx3g -Xmn1g -XX:PermSize=128m -XX:MaxPermSize=128m -XX:+UseConcMarkSweepGC

环境信息如下:
操作系统:
Linux linux-wgvb 2.6.16.60-0.54.5-smp #1 SMP Fri Sep 4 01:28:03 UTC 2009 x86_64 x86_64 x86_64 GNU/Linux

JDK版本:
java version "1.6.0_32"
Java(TM) SE Runtime Environment (build 1.6.0_32-b05)
Java HotSpot(TM) 64-Bit Server VM (build 20.7-b02, mixed mode)


1、这时FullGC是正常的没错,但是不正常的是Xmx已经设置成3g了却不自动扩容,如果自动扩容了就不会有这么频繁的FullGC
2、你的这个计算方法是错的,Xms是初始分配的最小内存,不是FullGC后的内存,而自动扩展也不是要等到老生代100%才自动扩展,JVM的默认参数-XX:MinHeapFreeRatio=40是40%,也就是当前的剩余内存已经不足40%后会增大内存上限值。另外,那个0.7我估计你把-XX:MaxHeapFreeRatio=70理解错了。
3、jmap的命令之前已经看过了,新生代、老生代、永久代代信息与jstat -gccapacity基本一致
4、Xms、Xmx设置成一致之前也已经试过了,但我发这个帖子的疑问是-Xms256m -Xmx3072m的情况下为何不会自动扩容。 (PS:Xms、Xmx设置成一致也得考虑GC时间变长带来的影响,虽说设置成一样可以减少内存自动扩张和收缩带来的性能损失)
0 请登录后投票
   发表时间:2013-01-23  
1、这时FullGC是正常的没错,但是不正常的是Xmx已经设置成3g了却不自动扩容,如果自动扩容了就不会有这么频繁的FullGC

我觉得应该是自动扩容了,只是在你上面的日志中没有体现出来。我做了一下测试,只不过每次扩容的比例不是很大,具体请参考如下的实验。

2、你的这个计算方法是错的,Xms是初始分配的最小内存,不是FullGC后的内存,而自动扩展也不是要等到老生代100%才自动扩展,JVM的默认参数-XX:MinHeapFreeRatio=40是40%,也就是当前的剩余内存已经不足40%后会增大内存上限值。另外,那个0.7我估计你把-XX:MaxHeapFreeRatio=70理解错了。

这个确实是我理解错了,但是实验后发现,这个设置基本上解释不通。因为每次扩容并不是严格按照空闲堆空间小于40%的规则,具体见如下的实验。

3、jmap的命令之前已经看过了,新生代、老生代、永久代代信息与jstat -gccapacity基本一致

我实验时使用jstat -gcutil 命令也没有发现自动扩容(主要从百分比上分析),但是使用了jstat -gc查看发现确实扩容了,同时使用 jmap -heap 每隔一段时间取dump,也印证了确实自动扩容了。

4、Xms、Xmx设置成一致之前也已经试过了,但我发这个帖子的疑问是-Xms256m -Xmx3072m的情况下为何不会自动扩容。 (PS:Xms、Xmx设置成一致也得考虑GC时间变长带来的影响,虽说设置成一样可以减少内存自动扩张和收缩带来的性能损失)

实验说明:
1.编写java测试代码:
public class GCDemo {

    public static void main(String[] args) throws Exception {
        System.out.println("start");
        Thread.sleep(20000);

        System.out.println("1/2m");
        byte[] bytes1 = new byte[1024 * 1024 * 2];
        Thread.sleep(8000);

        System.out.println("2/2m");
        byte[] bytes2 = new byte[1024 * 1024 * 2];
        Thread.sleep(8000);

        System.out.println("3/2m");
        byte[] bytes3 = new byte[1024 * 1024 * 2];
        Thread.sleep(30000);

        System.out.println("1/4m");
        byte[] bytes4 = new byte[1024 * 1024 * 4];
        Thread.sleep(30000);
        bytes4 = null;

        System.out.println("2/4m");
        byte[] bytes5 = new byte[1024 * 1024 * 4];
        Thread.sleep(30000);

        System.out.println("3/4m");
        byte[] bytes6 = new byte[1024 * 1024 * 4];
        Thread.sleep(30000);
    }
}

2.使用如下命令启动:
java -Xms4m -Xmx48m  -XX:+UseParallelOldGC -XX:MaxGCPauseMillis=1000 -XX:ParallelGCThreads=5 -Xrs -XX:PermSize=64m -XX:MaxPermSize=64m -XX:+HeapDumpOnOutOfMemoryError com.dinstone.practice.jvm.GCDemo

3.使用jstat -gc 4664 2000观察:
[root@appserver13 ~]# jstat -gc 4664 2000
S0C    S1C    S0U    S1U      EC       EU        OC         OU       PC     PU   
512.0  512.0   0.0    0.0    3072.0   270.0     2752.0      0.0     65536.0 3463.2
512.0  512.0   0.0    0.0    3072.0   270.0     2752.0      0.0     65536.0 3463.2
512.0  512.0   0.0    0.0    3072.0   270.0     2752.0      0.0     65536.0 3463.2
512.0  512.0   0.0    0.0    3072.0   270.0     2752.0      0.0     65536.0 3463.2
512.0  512.0   0.0    0.0    3072.0   2379.5    2752.0      0.0     65536.0 3463.3
512.0  512.0   0.0    0.0    3072.0   2379.5    2752.0      0.0     65536.0 3463.3
512.0  512.0   0.0    0.0    3072.0   2379.5    2752.0      0.0     65536.0 3463.3
512.0  512.0   0.0    0.0    3072.0   2379.5    2752.0      0.0     65536.0 3463.3
512.0  512.0   0.0    0.0    3072.0   2379.5    2752.0     2048.0   65536.0 3463.3
512.0  512.0   0.0    0.0    3072.0   2379.5    2752.0     2048.0   65536.0 3463.3
512.0  512.0   0.0    0.0    3072.0   2379.5    2752.0     2048.0   65536.0 3463.3
512.0  512.0   0.0    0.0    3072.0   2379.5    2752.0     2048.0   65536.0 3463.3
512.0  512.0   0.0    0.0    3072.0   2379.5    4864.0     4096.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    4864.0     4096.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    4864.0     4096.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    4864.0     4096.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    4864.0     4096.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    4864.0     4096.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    4864.0     4096.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    4864.0     4096.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    4864.0     4096.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    4864.0     4096.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    4864.0     4096.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    4864.0     4096.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    4864.0     4096.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    4864.0     4096.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    4864.0     4096.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    9024.0     8192.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    9024.0     8192.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    9024.0     8192.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    9024.0     8192.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    9024.0     8192.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    9024.0     8192.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    9024.0     8192.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    9024.0     8192.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    9024.0     8192.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    9024.0     8192.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    9024.0     8192.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    9024.0     8192.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    9024.0     8192.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    9024.0     8192.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5    9024.0     8192.0   65536.0 3463.4
512.0  512.0   0.0    0.0    3072.0   2379.5   13184.0    12288.1   65536.0 3463.5
512.0  512.0   0.0    0.0    3072.0   2379.5   13184.0    12288.1   65536.0 3463.5
512.0  512.0   0.0    0.0    3072.0   2379.5   13184.0    12288.1   65536.0 3463.5
512.0  512.0   0.0    0.0    3072.0   2379.5   13184.0    12288.1   65536.0 3463.5
512.0  512.0   0.0    0.0    3072.0   2379.5   13184.0    12288.1   65536.0 3463.5
512.0  512.0   0.0    0.0    3072.0   2379.5   13184.0    12288.1   65536.0 3463.5
512.0  512.0   0.0    0.0    3072.0   2379.5   13184.0    12288.1   65536.0 3463.5
512.0  512.0   0.0    0.0    3072.0   2379.5   13184.0    12288.1   65536.0 3463.5
512.0  512.0   0.0    0.0    3072.0   2379.5   13184.0    12288.1   65536.0 3463.5
512.0  512.0   0.0    0.0    3072.0   2379.5   13184.0    12288.1   65536.0 3463.5
512.0  512.0   0.0    0.0    3072.0   2379.5   13184.0    12288.1   65536.0 3463.5
512.0  512.0   0.0    0.0    3072.0   2379.5   13184.0    12288.1   65536.0 3463.5
512.0  512.0   0.0    0.0    3072.0   2379.5   13184.0    12288.1   65536.0 3463.5
512.0  512.0   0.0    0.0    3072.0   2379.5   13184.0    12288.1   65536.0 3463.5
512.0  512.0   0.0    0.0    3072.0   2379.5   13184.0    12288.1   65536.0 3463.5
512.0  512.0   0.0    0.0    3072.0   2379.5   17344.0    16384.1   65536.0 3463.6
512.0  512.0   0.0    0.0    3072.0   2379.5   17344.0    16384.1   65536.0 3463.6
512.0  512.0   0.0    0.0    3072.0   2379.5   17344.0    16384.1   65536.0 3463.6
512.0  512.0   0.0    0.0    3072.0   2379.5   17344.0    16384.1   65536.0 3463.6
512.0  512.0   0.0    0.0    3072.0   2379.5   17344.0    16384.1   65536.0 3463.6
512.0  512.0   0.0    0.0    3072.0   2379.5   17344.0    16384.1   65536.0 3463.6
512.0  512.0   0.0    0.0    3072.0   2379.5   17344.0    16384.1   65536.0 3463.6
512.0  512.0   0.0    0.0    3072.0   2379.5   17344.0    16384.1   65536.0 3463.6
512.0  512.0   0.0    0.0    3072.0   2379.5   17344.0    16384.1   65536.0 3463.6
512.0  512.0   0.0    0.0    3072.0   2379.5   17344.0    16384.1   65536.0 3463.6
512.0  512.0   0.0    0.0    3072.0   2379.5   17344.0    16384.1   65536.0 3463.6
512.0  512.0   0.0    0.0    3072.0   2379.5   17344.0    16384.1   65536.0 3463.6
512.0  512.0   0.0    0.0    3072.0   2379.5   17344.0    16384.1   65536.0 3463.6
512.0  512.0   0.0    0.0    3072.0   2379.5   17344.0    16384.1   65536.0 3463.6
512.0  512.0   0.0    0.0    3072.0   2379.5   17344.0    16384.1   65536.0 3463.6

4.实验分析
由 OC/OU 值的变化 2752/2048 -> 4864/4096 -> 9024/8192 -> 13184/12288 -> 17344/16384 可见,
1)确实自动扩容了
2)每次的扩容没有什么规律

希望对你有用!
0 请登录后投票
   发表时间:2013-01-23  
dinstone 写道
1、这时FullGC是正常的没错,但是不正常的是Xmx已经设置成3g了却不自动扩容,如果自动扩容了就不会有这么频繁的FullGC

我觉得应该是自动扩容了,只是在你上面的日志中没有体现出来。我做了一下测试,只不过每次扩容的比例不是很大,具体请参考如下的实验。

2、你的这个计算方法是错的,Xms是初始分配的最小内存,不是FullGC后的内存,而自动扩展也不是要等到老生代100%才自动扩展,JVM的默认参数-XX:MinHeapFreeRatio=40是40%,也就是当前的剩余内存已经不足40%后会增大内存上限值。另外,那个0.7我估计你把-XX:MaxHeapFreeRatio=70理解错了。

这个确实是我理解错了,但是实验后发现,这个设置基本上解释不通。因为每次扩容并不是严格按照空闲堆空间小于40%的规则,具体见如下的实验。

3、jmap的命令之前已经看过了,新生代、老生代、永久代代信息与jstat -gccapacity基本一致

我实验时使用jstat -gcutil 命令也没有发现自动扩容(主要从百分比上分析),但是使用了jstat -gc查看发现确实扩容了,同时使用 jmap -heap 每隔一段时间取dump,也印证了确实自动扩容了。

4、Xms、Xmx设置成一致之前也已经试过了,但我发这个帖子的疑问是-Xms256m -Xmx3072m的情况下为何不会自动扩容。 (PS:Xms、Xmx设置成一致也得考虑GC时间变长带来的影响,虽说设置成一样可以减少内存自动扩张和收缩带来的性能损失)

实验说明:
1.编写java测试代码:
public class GCDemo {

    public static void main(String[] args) throws Exception {
        System.out.println("start");
        Thread.sleep(20000);

        System.out.println("1/2m");
        byte[] bytes1 = new byte[1024 * 1024 * 2];
        Thread.sleep(8000);

        System.out.println("2/2m");
        byte[] bytes2 = new byte[1024 * 1024 * 2];
        Thread.sleep(8000);

        System.out.println("3/2m");
        byte[] bytes3 = new byte[1024 * 1024 * 2];
        Thread.sleep(30000);

        System.out.println("1/4m");
        byte[] bytes4 = new byte[1024 * 1024 * 4];
        Thread.sleep(30000);
        bytes4 = null;

        System.out.println("2/4m");
        byte[] bytes5 = new byte[1024 * 1024 * 4];
        Thread.sleep(30000);

        System.out.println("3/4m");
        byte[] bytes6 = new byte[1024 * 1024 * 4];
        Thread.sleep(30000);
    }
}

2.使用如下命令启动:
java -Xms4m -Xmx48m  -XX:+UseParallelOldGC -XX:MaxGCPauseMillis=1000 -XX:ParallelGCThreads=5 -Xrs -XX:PermSize=64m -XX:MaxPermSize=64m -XX:+HeapDumpOnOutOfMemoryError com.dinstone.practice.jvm.GCDemo

3.使用jstat -gc 4664 2000观察:
4.实验分析
由 OC/OU 值的变化 2752/2048 -> 4864/4096 -> 9024/8192 -> 13184/12288 -> 17344/16384 可见,
1)确实自动扩容了
2)每次的扩容没有什么规律

希望对你有用!


谢谢你的答复,其实之前我也写测试代码试过了用与那个应用程序相同的JVM参数内存是可以正常扩展的,但是不知道为啥这个应用程序的内存就是不能自动扩展(PS:是在大压力环境下)。怀疑-XX:+UseParallelOldGC 在压力测试场景下可能有问题,在sun的网站上好像也看到-XX:+UseParallelOldGC 在压力测试场景下相关的bug说明。
0 请登录后投票
   发表时间:2013-01-24  
从实验的结果来看,我们都看到了内存是会扩展的,但是这个扩展是不满足-XX:MinHeapFreeRatio和-XX:MaxHeapFreeRatio设置的。经查证,发现当使用-XX:+UseParallelOldGC参数时,俩个参数是不适用的。
参考如下:Java SE 6 HotSpot[tm] Virtual Machine Garbage Collection Tuning(http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html#par_gc.ergonomics)中Total Heap一节.
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics