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

参考资料

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

gc实例与gc报告的阅读的更多相关文章

  1. GC参考手册 —— GC 调优(工具篇)

    JVM 在程序执行的过程中, 提供了GC行为的原生数据.那么, 我们就可以利用这些原生数据来生成各种报告.原生数据(raw data) 包括: 各个内存池的当前使用情况, 各个内存池的总容量, 每次G ...

  2. GC参考手册 —— GC 算法(实现篇)

    学习了GC算法的相关概念之后, 我们将介绍在JVM中这些算法的具体实现.首先要记住的是, 大多数JVM都需要使用两种不同的GC算法 —— 一种用来清理年轻代, 另一种用来清理老年代. 我们可以选择JV ...

  3. System.gc()与Runtime.gc()的区别

    (1) GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象 ...

  4. Java GC工作原理以及Minor GC、Major GC、Full GC简单总结

    名词解释: GC:垃圾收集器 Minor GC:新生代GC,指发生在新生代的垃圾收集动作,所有的Minor GC都会触发全世界的暂停(stop-the-world),停止应用程序的线程,不过这个过程非 ...

  5. Java虚拟机6:内存溢出和内存泄露、并行和并发、Minor GC和Full GC、Client模式和Server模式的区别

    前言 之前的文章尤其是讲解GC的时候提到了很多的概念,比如内存溢出和内存泄露.并行与并发.Client模式和Server模式.Minor GC和Full GC,本文详细讲解下这些概念的区别. 内存溢出 ...

  6. -Xloggc:log/gc.log 指定GC log的位置

    -Xloggc:log/gc.log指定GC log的位置,以文件输出帮助开发人员分析问题

  7. Minor GC、Major GC和Full GC之间的区别(转)

    在 Plumbr 从事 GC 暂停检测相关功能的工作时,我被迫用自己的方式,通过大量文章.书籍和演讲来介绍我所做的工作.在整个过程中,经常对 Minor.Major.和 Full GC 事件的使用感到 ...

  8. minor gc 和 full gc

    JAVA中关于GC的分析中,需要搞清楚,GC线程在什么时候,对什么东西,做了什么操作. 1-在什么时候 首先需要知道,GC分为minor GC和full GC,JAVA内存分为新生代和老年代,新生代中 ...

  9. Minor GC、Major GC和Full GC之间的区别

    在 Plumbr 从事 GC 暂停检测相关功能的工作时,我被迫用自己的方式,通过大量文章.书籍和演讲来介绍我所做的工作.在整个过程中,经常对 Minor.Major.和 Full GC 事件的使用感到 ...

随机推荐

  1. springMVC源码分析--HandlerMethodArgumentResolver参数解析器(一)

    HandlerMethodArgumentResolver是用来为处理器解析参数的,主要用在HandlerMethod中,每个Resolver对应一种类型的参数,其实现类特别的多. HandlerMe ...

  2. Bootstrap3 栅格系统-实例:从堆叠到水平排列

    使用单一的一组 .col-md-* 栅格类,就可以创建一个基本的栅格系统,在手机和平板设备上一开始是堆叠在一起的(超小屏幕到小屏幕这一范围),在桌面(中等)屏幕设备上变为水平排列.所有"列( ...

  3. RAP在线接口管理统计部署

    文档: https://github.com/thx/RAP/wiki/home_cn centos上部署 参考:https://github.com/thx/RAP/wiki/deploy_on_c ...

  4. Python Generator 运行细节验证

    今天来__next__和send, 改天来throw和close class A: def __setattr__(self, key, val): print('set %s to %s'%(key ...

  5. tomcat自动运行磁盘任意位置上的项目、使用Maven对tomcat进行自动部署

     对于非Maven的web项目,有时候我们想不时常通过打war包.拷贝war包.启动tomcat来运行项目.这时候我们可以通过以下方式来进行配置: 1.1:创建web工程.工程结构如下: 1.2. ...

  6. Android使用HttpClient以Post、Get请求服务器发送数据的方式(普通和json)

    讲这个之前,我们先来说说get和post两种请求的区别吧!!! 1. GET提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连,如EditPosts.jsp?name=te ...

  7. tf.app.run()

    在很多TensorFlow公布的Demo中,都有这样的代码存在,如下,这是干什么的呢? if __name__ == "__main__": tf.app.run() 我们来看一下 ...

  8. 转义字符\(在hive+shell以及java中注意事项):正则表达式的转义字符为双斜线,split函数解析也是正则

    转义字符 将后边字符转义,使特殊功能字符作为普通字符处理,或者普通字符转化为特殊功能字符. 各个语言中都用应用,如java.python.sql.hive.shell等等. 如sql中 "\ ...

  9. 使用Broadcast实现android组件之间的通信

    android组件之间的通信有多种实现方式,Broadcast就是其中一种.在activity和fragment之间的通信,broadcast用的更多本文以一个activity为例. 效果如图: 布局 ...

  10. UE4利用Save Game创建全局变量

    因为盲目的做了一个UE4的项目,没有用到UE4的无缝加载,我只能在一个个关卡中手动切换,然后每次的数据都会重置,这对于项目来说,造成了体验感的极度下降. 然而我查了一下怎样在UE4中创建全局变量,找到 ...