本文是 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. Acdreamoj1115(数学思维称号)

    意甲冠军:1,3是完美的数,假定a,b是完美的数,然后,2+a*b+2*a+2*b,结论认为,n无论是完美的数字. 解法:開始仅仅看出来2+a*b+2*a+2*b=(a+2)*(b+2)-2,没推出很 ...

  2. [LeetCode129]Sum Root to Leaf Numbers

    题目: Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a nu ...

  3. WPF异步载入图片,附带载入中动画

    原文:WPF异步载入图片,附带载入中动画 WPF异步载入图片,附带载入中动画 最近,在做一个WPF项目.项目中有一个需求,就是以列表的方式显示出项目图片.这些图片有的存在于互联网上,有的存在于本地磁盘 ...

  4. MVC Code First (代码优先)

    首先配置web.config <connectionStrings> <add name="BookDbContext" connectionString=&qu ...

  5. 可以改变文本行距(行间距)的Label

    ////////////////////////////////////////////////////// /// ///功能:可以改变文本行距(行间距)的Label ///作者:emanlee / ...

  6. Eclipse4.4设备egit插件提交本地项目代码到远程仓库

    一.设备egit 打开Eclipse的Marketplace.在搜索框中输入egit就可以,能够看到Eclipse4.4已经默认安装了egit,当然假设有新版本号的egit公布的话,也能够在下图上点击 ...

  7. 好的安排小明(南阳19)(DFS)

    擅长排列的小明 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描写叙述 小明十分聪明,并且十分擅长排列计算.比方给小明一个数字5,他能立马给出1-5按字典序的全排列,假设你想 ...

  8. Android+NDK+CDT+eclipse+OPenGL ES编制和native调试

    周围环境: NDK版本号r8,eclipse和Android运用adt-bundle-windows-x86打包版本是更方便, 一.NDK汇集 1.源代码 NDK的examples文件夹中有Hello ...

  9. Android应用公布的准备——生成渠道包

    我们须要使用一个变量标明该app的渠道.通常我们能够在manifest中的application节点下声明.例如以下. <meta-data android:name="CHANNEL ...

  10. 一天JavaScript示例-判定web页面的区域

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...