gc实例与gc报告的阅读

来源:互联网 发布:土方平衡计算软件 编辑:程序博客网 时间:2024/06/05 03:02
gc报告的阅读
首先我们看一条gc报告
D:\杂项\java>java -verbose:gc -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails  -XX:+UseSerialGC -XX:SurvivorRatio=8 testAllocation[GC[DefNew: 7492K->980K(9216K), 0.0034913 secs] 7492K->7124K(19456K), 0.0037735 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]Heap def new generation   total 9216K, used 3358K [0x00000000f9a00000, 0x00000000fa400000, 0x00000000fa400000)  eden space 8192K,  29% used [0x00000000f9a00000, 0x00000000f9c52728, 0x00000000fa200000)  from space 1024K,  95% used [0x00000000fa300000, 0x00000000fa3f5100, 0x00000000fa400000)  to   space 1024K,   0% used [0x00000000fa200000, 0x00000000fa200000, 0x00000000fa300000) tenured generation   total 10240K, used 6144K [0x00000000fa400000, 0x00000000fae00000, 0x00000000fae00000)   the space 10240K,  60% used [0x00000000fa400000, 0x00000000faa00030, 0x00000000faa00200, 0x00000000fae00000) compacting perm gen  total 21248K, used 2471K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)   the space 21248K,  11% used [0x00000000fae00000, 0x00000000fb069d58, 0x00000000fb069e00, 0x00000000fc2c0000)No shared spaces configured.

先看java运行的几个参数

-Xms20m -Xmx20m -Xmn10m说明堆的大小固定不变,为20m,其中年轻代为10m
-XX:+PrintGCDetails 让虚拟机打印出gc日志,最后输出当前内存各个区域的使用情况。注意,这是两部分内容,一个是gc日志,一个是内存使用情况。
-XX:+UseSerialGC 使用-XX:+UseSerialGC可以使用Serial+Serial Old模式运行进行内存回收(这也是虚拟机在Client模式下运行的默认值)
-XX:SurvivorRatio=8 说明eden区与一个Survivor区的大小比例为8。


至于[GC[DefNew: 7492K->980K(9216K), 0.0034913 secs] 7492K->7124K(19456K), 0.0037735 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]具体是什么意思
大家参阅Java GC 日志详解
我就补充一点:日志开头的[GC和[Full GC说明了此次垃圾收集的停顿类型,而不是用来区分新生代GC还是老年代GC。


我们看几个实例
D:\杂项\java>type testAllocation2.java/** * *  -verbose:gc  -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails  -XX:SurvivorRatio=8 * */public class testAllocation2{        private static int _1m=1024*1024;        public static void main(String[] args) {                byte[] all1,all2,all3,all4,all5;                all1=new byte[_1m * 2];                all2=new byte[_1m * 2];                all3=new byte[_1m * 2];                all4=new byte[_1m * 4];        }}D:\杂项\java>javac testAllocation2.javaD:\杂项\java>java -verbose:gc  -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails  -XX:SurvivorRatio=8 testAllocation2Heap PSYoungGen      total 9216K, used 7143K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)  eden space 8192K, 87% used [0x00000000ff600000,0x00000000ffcf9ff8,0x00000000ffe00000)  from space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)  to   space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000) ParOldGen       total 10240K, used 4096K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)  object space 10240K, 40% used [0x00000000fec00000,0x00000000ff000010,0x00000000ff600000) PSPermGen       total 21504K, used 2468K [0x00000000f9a00000, 0x00000000faf00000, 0x00000000fec00000)  object space 21504K, 11% used [0x00000000f9a00000,0x00000000f9c691d0,0x00000000faf00000)D:\杂项\java>


上面的代码是我从<<深入理解java虚拟机>>第二章中引过来的。但是并没有发生gc呀?


花了好长时间,才知道得加上一个参数。
-XX:+UseSerialGC
不是说默认就是这个参数么?
我的java版本:
D:\杂项\java>java -versionjava version "1.7.0_67"Java(TM) SE Runtime Environment (build 1.7.0_67-b01)Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)
搞不清楚了。
我们加上这个参数


D:\杂项\java>java -verbose:gc  -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails -XX:+UseSerialGC  -XX:SurvivorRatio=8 testAllocation2[GC[DefNew: 6980K->468K(9216K), 0.0034679 secs] 6980K->6612K(19456K), 0.0037547 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]Heap def new generation   total 9216K, used 4894K [0x00000000f9a00000, 0x00000000fa400000, 0x00000000fa400000)  eden space 8192K,  54% used [0x00000000f9a00000, 0x00000000f9e527b0, 0x00000000fa200000)  from space 1024K,  45% used [0x00000000fa300000, 0x00000000fa3750f0, 0x00000000fa400000)  to   space 1024K,   0% used [0x00000000fa200000, 0x00000000fa200000, 0x00000000fa300000) tenured generation   total 10240K, used 6144K [0x00000000fa400000, 0x00000000fae00000, 0x00000000fae00000)   the space 10240K,  60% used [0x00000000fa400000, 0x00000000faa00030, 0x00000000faa00200, 0x00000000fae00000) compacting perm gen  total 21248K, used 2471K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)   the space 21248K,  11% used [0x00000000fae00000, 0x00000000fb069cf8, 0x00000000fb069e00, 0x00000000fc2c0000)No shared spaces configured.D:\杂项\java>

OK,发生gc了。
all1,all2,all3加入后,eden区域已经被占了6m了,本来就只有8m,all4的4m一来,马上就发生Minor gc
6m的对象中没有任何一个能放入一个survivor区,那没办法了,6m的对象直接进入老年代。
tenured generation   total 10240K, used 6144K [0x00000000fa400000, 0x00000000fae00000, 0x00000000fae00000)
   the space 10240K,  60% used [0x00000000fa400000, 0x00000000faa00030, 0x00000000faa00200, 0x00000000fae00000)
能说明这个问题。
那么all4呢,它的4m,就还是放到eden区。
我们再看一个例子。
private static int _0_5M=1024*512;public static void main(String[] args) {byte[] all1,all2,all3,all4,all5;all1=new byte[1*_0_5M];all2=new byte[4*_0_5M];all3=new byte[4*_0_5M];all4=new byte[4*_0_5M];all5=new byte[4*_0_5M];}

结果
D:\杂项\java>java -verbose:gc  -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails -XX:+UseSerialGC  -XX:SurvivorRatio=8 testAllocation[GC[DefNew: 7492K->980K(9216K), 0.0036395 secs] 7492K->7124K(19456K), 0.0038973 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]Heap def new generation   total 9216K, used 3358K [0x00000000f9a00000, 0x00000000fa400000, 0x00000000fa400000)  eden space 8192K,  29% used [0x00000000f9a00000, 0x00000000f9c52728, 0x00000000fa200000)  from space 1024K,  95% used [0x00000000fa300000, 0x00000000fa3f5100, 0x00000000fa400000)  to   space 1024K,   0% used [0x00000000fa200000, 0x00000000fa200000, 0x00000000fa300000) tenured generation   total 10240K, used 6144K [0x00000000fa400000, 0x00000000fae00000, 0x00000000fae00000)   the space 10240K,  60% used [0x00000000fa400000, 0x00000000faa00030, 0x00000000faa00200, 0x00000000fae00000) compacting perm gen  total 21248K, used 2471K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)   the space 21248K,  11% used [0x00000000fae00000, 0x00000000fb069d00, 0x00000000fb069e00, 0x00000000fc2c0000)No shared spaces configured.D:\杂项\java>

all5产生时发生了minor gc,与上面的例子不同的时,最后:all2,all3,all4进入了老年代,而all1与all5共2.5m进入了eden区。
那怎么survivor还占用了95%,这个我估计是堆里的其他数据。大家忽略之。


感谢glt


参考资料

http://blog.csdn.net/alivetime/article/details/6895537



0 0
原创粉丝点击