本文是 Plumbr 发行的 Java垃圾收集手册 的部分内容。文中将介绍GC日志的输出格式, 以及如何解读GC日志, 从中提取有用的信息。我们通过 -XX:+UseSerialGC 选项,指定JVM使用串行垃圾收集器, 并使用下面的启动参数让 JVM 打印出详细的GC日志:

-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+PrintGCTimeStamps

这样配置以后,发生GC时输出的日志就类似于下面这种格式(为了显示方便,已手工折行):

2015-05-26T14:45:37.987-0200: 151.126:
[GC (Allocation Failure) 151.126:
[DefNew: 629119K->69888K(629120K), 0.0584157 secs]
1619346K->1273247K(2027264K), 0.0585007 secs]
[Times: user=0.06 sys=0.00, real=0.06 secs] 2015-05-26T14:45:59.690-0200: 172.829:
[GC (Allocation Failure) 172.829:
[DefNew: 629120K->629120K(629120K), 0.0000372 secs]
172.829: [Tenured: 1203359K->755802K(1398144K), 0.1855567 secs]
1832479K->755802K(2027264K),
[Metaspace: 6741K->6741K(1056768K)], 0.1856954 secs]
[Times: user=0.18 sys=0.00, real=0.18 secs]

上面的GC日志暴露了JVM中的一些信息。事实上,这个日志片段中发生了 2 次垃圾回收事件(Garbage Collection events)。其中一次清理的是年轻代(Young generation), 而第二次处理的是整个堆内存。下面我们来看,如何解读第一次GC事件,发生在年轻代中的小型GC(Minor GC):

2015-05-26T14:45:37.987-02001:151.1262:[GC3(Allocation Failure4)
151.126: [DefNew5:629119K->69888K6(629120K)7
, 0.0584157 secs]1619346K->1273247K8(2027264K)9,0.0585007 secs10]
[Times: user=0.06 sys=0.00, real=0.06 secs]
11

  1. 2015-05-26T14:45:37.987-0200 – GC事件(GC event)开始的时间点.
  2. 151.126 – GC时间的开始时间,相对于JVM的启动时间,单位是秒(Measured in seconds).
  3. GC – 用来区分(distinguish)是 Minor GC 还是 Full GC 的标志(Flag). 这里的 GC 表明本次发生的是 Minor GC.
  4. Allocation Failure – 引起垃圾回收的原因. 本次GC是因为年轻代中没有任何合适的区域能够存放需要分配的数据结构而触发的.
  5. DefNew – 使用的垃圾收集器的名字. DefNew 这个名字代表的是: 单线程(single-threaded), 采用标记复制(mark-copy)算法的, 使整个JVM暂停运行(stop-the-world)的年轻代(Young generation) 垃圾收集器(garbage collector).
  6. 629119K->69888K – 在本次垃圾收集之前和之后的年轻代内存使用情况(Usage).
  7. (629120K) – 年轻代的总的大小(Total size).
  8. 1619346K->1273247K – 在本次垃圾收集之前和之后整个堆内存的使用情况(Total used heap).
  9. (2027264K) – 总的可用的堆内存(Total available heap).
  10. 0.0585007 secs – GC事件的持续时间(Duration),单位是秒.
  11. [Times: user=0.06 sys=0.00, real=0.06 secs] – GC事件的持续时间,通过多种分类来进行衡量: 
    • user – 此次垃圾回收, 垃圾收集线程消耗的所有CPU时间(Total CPU time).
    • sys – 操作系统调用(OS call) 以及等待系统事件的时间(waiting for system event)
    • real – 应用程序暂停的时间(Clock time). 由于串行垃圾收集器(Serial Garbage Collector)只会使用单个线程, 所以 real time 等于 user 以及 system time 的总和.

通过上面的分析, 我们可以计算出在垃圾收集期间, JVM 中的内存使用情况。在垃圾收集之前, 堆内存总的使用了1.54G (1,619,346K)。其中, 年轻代使用了 614M(629,119k)。可以算出老年代使用的内存为: 967M(990,227K)。

下一组数据( -> 右边)中蕴含了更重要的结论, 年轻代的内存使用在垃圾回收后下降了 546M(559,231k), 但总的堆内存使用(total heap usage)只减少了 337M(346,099k). 通过这一点,我们可以计算出, 有 208M(213,132K) 的年轻代对象被提升到老年代(Old)中。

这个GC事件可以用下面的示意图来表示, 上方表示GC之前的内存使用情况, 下方表示结束后的内存使用情况:

如果你想学习更多, 请查看完整的 Java垃圾收集手册, 本示例是从其中抽取的。

原文链接: Understanding Garbage Collection Logs

翻译日期: 2015年10月18日

翻译人员: 铁锚 http://blog.csdn.net/renfufei

http://blog.csdn.net/renfufei/article/details/49230943

快速解读GC日志(转)的更多相关文章

  1. 快速解读GC日志

    本文是 Plumbr 发行的 Java垃圾收集指南 的部分内容.文中将介绍GC日志的输出格式, 以及如何解读GC日志, 从中提取有用的信息.我们通过 -XX:+UseSerialGC 选项,指定JVM ...

  2. 《深入理解Java虚拟机》(六)堆内存使用分析,垃圾收集器 GC 日志解读

    堆内存使用分析,GC 日志解读 重要的东东 在Java中,对象实例都是在堆上创建.一些类信息,常量,静态变量等存储在方法区.堆和方法区都是线程共享的. GC机制是由JVM提供,用来清理需要清除的对象, ...

  3. jvm gc日志解读

    参考 https://blog.csdn.net/yxc135/article/details/12137663 认识gc日志每个位置的含义 java 8 full gc [Full GC (Meta ...

  4. 【转载】Java垃圾回收内存清理相关(虚拟机书第三章),GC日志的理解,CPU时间、墙钟时间的介绍

    主要看<深入理解Java虚拟机> 第三张 P84 开始是垃圾收集相关. 1. 1960年诞生于MIT的Lisp是第一门采用垃圾回收的语言. 2. 程序计数器.虚拟机栈.本地方法栈3个区域随 ...

  5. 【译】深入理解G1的GC日志(一)

    本文翻译自:https://www.redhat.com/en/blog/collecting-and-reading-g1-garbage-collector-logs-part-2?source= ...

  6. 【转】gc日志分析工具

    性能测试排查定位问题,分析调优过程中,会遇到要分析gc日志,人肉分析gc日志有时比较困难,相关图形化或命令行工具可以有效地帮助辅助分析. Gc日志参数 通过在tomcat启动脚本中添加相关参数生成gc ...

  7. JVM实用参数(八)GC日志

    本系列的最后一部分是有关垃圾收集(GC)日志的JVM参数.GC日志是一个很重要的工具,它准确记录了每一次的GC的执行时间和执行结果,通过分析GC日志可以优化堆设置和GC设置,或者改进应用程序的对象分配 ...

  8. GC之七--gc日志分析工具

    性能测试排查定位问题,分析调优过程中,会遇到要分析gc日志,人肉分析gc日志有时比较困难,相关图形化或命令行工具可以有效地帮助辅助分析. Gc日志参数 通过在tomcat启动脚本中添加相关参数生成gc ...

  9. 理解GC日志

    每一种收集器的日志形式都是由它们自身的实现所决定的,换而言之,每个收集器的日志格式都可以不一样.但虚拟机设计者为了方便用户阅读,将各个收集器的日志都维持一定的共性,例如以下两段典型的GC日志: 33. ...

随机推荐

  1. nyoj 117 找到的倒数 【树阵】+【分离】

    这个问题的解决方案是真的很不错!!! 思路:建立一个结构体包括val和id. val就是输入的数,id表示输入的顺序.然后依照val从小到大排序.假设val相等.那么就依照id排序. 假设没有逆序的话 ...

  2. android 4.0 中出错 java.lang.UnsupportedOperationException

    在android4.0中  画图的时候使用: canvas.clipPath(path, Region.Op.XOR); 报错 java.lang.UnsupportedOperationExcept ...

  3. 在汉澳sinox2014建立ZFS高可靠文件存储系统

    在汉澳sinox2014建立ZFS高可靠文件存储系统 汉澳sinox2014能够用比較小的固态硬盘安装,文件系统能够用zfs系统存放. 请准备一些硬盘,比方三块SCSI硬盘:da0,da1,da2 如 ...

  4. JDK源代码学习系列07----Stack

                                                                   JDK源代码学习系列07----Stack 1.Stack源代码很easy ...

  5. Web Reference for a WCF Service has Extra “IdSpecified” Parameter ?

    Question: I created a WCF service that exposed a method that has one paramater: public class Service ...

  6. WMI 获取硬件信息的封装函数与获取联想台式机的出厂编号方法

    原文:WMI 获取硬件信息的封装函数与获取联想台式机的出厂编号方法 今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都是可以提取出来的,就自己把那些公共部分提出出来,以后如果要获取 某部分的 ...

  7. IntelliJ 15 unmapped spring configuration files found

    IntelliJ Spring Configuration Check 用IntelliJ 导入现有工程时,如果原来的工程中有spring,每次打开工程就会提示:Spring Configuratio ...

  8. 开源通讯组件ec

    跨平台开源通讯组件elastic communication elastic communication是基于c#开发支持.net和mono的通讯组件(简称EC),EC的主要目的简化mono和.net ...

  9. ruby简单的基本 3

    类 Ruby一切都是对象,它包含了一个恒定.例如,可以使用.class物业查看对象的类型,你可以看一下1.class.你会发现常1类型是Fixnum,1但它是Fixnum的一个例子. Ruby本类cl ...

  10. 【原版的】Redis事件驱动内核

    Redis事件驱动内核 作者:cf (360电商技术组) 概述 Redis实现了自己的事件驱动,与开源事件库libevent.libev一样,都是基于I/O多路复用技术实现的.出于性能和代码精炼双方面 ...