0
点赞
收藏
分享

微信扫一扫

gc实例与gc报告的阅读


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.java


D:\杂项\java>java -verbose:gc -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails -XX:SurvivorRatio=8 testAllocation2
Heap
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 -version
java 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



举报

相关推荐

0 条评论