存档

文章标签 ‘gc日志分析’

用HPjtune分析GC日志(一个实际案例的诊断过程)

2009年7月2日 hashei 6 条评论

上次介绍了IBM的两款分析gc log的工具(GCMV和PMAT),这次讲讲HP推出的HPjmeter。HPjmeter集成了以前的HPjtune功能,可以分析在HP机器上产生的垃圾回收日志文件。你可以到Hewlett-Packard Java website免费下载最新的4.0版本,当然会让你填一些信息。

接下来我将分析一个实际生产环境下的日志文件,这个生产系统在启用新的功能后应用访问速度变慢,每个操作都要耗时10s左右,通过对比前后不同的gc信息,希望能从JVM的层面来优化当前的性能。

HP小机(Pa-Risc和安腾平台)使用HP的JDK后,使用-Xloggc:filename或者-Xverbosegc:file=filename参数会生成形如

<GCH: vmrelease=”1.4.2 1.4.2.10-060112-16:07-PA_RISC2.0 PA2.0 (aCC_AP)
……
<GCH: mode=n >
<GCH: ncpu=8 >
<GCH: availswap=33554432 >
<GCH: usedswap=0 >
……
<GC: 2 4  9.625554 1 0 31 48539536 0 286392320 0 0 35782656 0 2409608 715849728 20971424 20971424 20971520 0.279391 0.279391 >
<GC: 2 4  10.879321 2 0 31 9797920 0 286392320 0 0 35782656 2409608 2742416 715849728 25165568 25165568 25165824 0.307422 0.307422 >

的日志,这种格式人肉分析就别想了,它可以在PMAT中以Xverbosegc/hpux文件格式打开,但是图象功能我这里没法使用,只好求助于HP自家的工具——HPjmeter了。

分析过程

用HPjmeter加载日志文件后,会自动打开HPjtune的窗口。首先会看到Heap Usage After GC标签页,这是四月份正常的情况(请先忽略systemgc,这点留待后面分析)

阅读全文…

WebSphere troubshooting-用工具分析GC Log

2009年6月9日 hashei 没有评论

要进行gc performance tuning,不得不对gc log进行分析。之前说到了“人肉”的方法,总觉得不够形象,无法让不了解的开发人员抑或是技术负责人有个直观的了解,所以本文介绍几个分析GC log的工具。

首先需要下载IBM Support Assistant,下载之后就可以从Update-Tools add on中下载我们需要的工具了,ISA使用方法。ISA把所有的工具集成在一个界面内,省去了设置启动参数的麻烦,同时能保持最及时的更新。分析垃圾回收日志,我主要用“The IBM Monitoring and Diagnostic Tools for Java™ – Garbage Collection and Memory Visualizer”和“IBM Pattern Modeling and Analysis Tool for Java Garbage Collector (PMAT)”这两个工具。我会用实际例子来说明如何使用这个工具。

用Garbage Collection and Memory Visualizer载入native_stderr.log,首先你会看到

gclog1 点击展开大图

这是一个500分钟的垃圾回收曲线图,可以观察到一天以内的大致情况。总的来说,蓝色的Used heap(after collection)运行在“平行通道”内,没有走“上升通道”(炒股的朋友应该知道上升通道的图形是咋样的)。所以在Report这个标签内,可以看到“The memory usage of the application does not indicate any obvious leaks.”。

Report中的Summary是需要关注的,它向我们显示了GC发生的次数,所用的policy(optthruput),平均停顿时间248ms,平均间隔时间3.37分钟,还有垃圾回收的速率(垃圾产生多并非不好,反而是吞吐率高的一种表现)。

Summary

让我们再切回Line plot视图,现在可以框选某一个时间段进行放大,同时在右边Axes中选择X轴的坐标系,默认的是相对时间,以分钟为单位,适用于你的应用程序总在启动N个小时后出现问题。如果是每天固定时间发生性能问题,那么应该选用绝对时间。

默认的曲线开启了Heap size和Used heap(after collection),你可以根据需要,在VGC Pause Date和VGC Date、VGC Heap Data中勾选你需要查看的曲线。比如你觉得程序响应时间很长,那么可以勾选上Intervals between garbage collection triggers和Pause time,看看上一条曲线是否和下面一条靠的“太近”。

阅读全文…

JAVA性能优化-GC日志分析

2009年6月1日 hashei 1 条评论

前两篇说到IBM JDK和Sun的HotSpot JDK的调优策略,当中一直提到的重要一点是需要根据GC详细日志来调整参数的设置,那么当我们收集到日志后如何分析,如何根据日志的情况来调整参数?这就是本文所要阐述的。

使用IBM的JDK的Windows平台和AIX平台,我们只要在WebSphere管理控制台的java进程属性里勾选“详细垃圾回收”,那么就会在native_stdout.log中生成如下的信息。

image

这幅图很形象的给出了gc日志的主要关注点:垃圾回收的原因、垃圾回收的间隔、垃圾回收前后的剩余空间、垃圾回收持续的时间……

“nursery”表示这次分配失败(Allocation Failure)发生在新生代(nursery),是第44次(id=44)因为新生代的分配失败而进行垃圾回收了(开启GC日志以来),离上一次发生GC的间隔是12746ms,无法分配的空间大小是8216Byte,而进行垃圾回收前,新生代的可用空间为1776Byte,小于8216Byte,虽然年老区还剩余45%的空间,但是新的内存空间是无法直接在年老区分配的,由此引发了一次清理过程(scavenger)。

GC type表明了这次垃圾回收是一个清理过程,也是第44次scavenger过程,同时恰是第44个gc过程,说明没有发生过诸如<gc type=”global”>的垃圾回收过程。flipped objectcount说明将要把4523143个存活下来的对象被复制到了幸存区(survivor space),而73768个对象则经过多次幸存区的复制,有幸熬出头,被转移到了长存区(tenured space)。我们看到清理的倾斜比率(scavenger tiltratio)为89%,而不是对半开,说明经过多次复制清理,JVM已经意识到每次只有很少的对象能存活下来,于是它自动增大了年轻代中Eden区的大小,以使得为新对象可以腾出更多的内存。

接下来的就比较简单,经过垃圾回收,新生代的空间剩余89%,因为分配失败发生在新生代,进行的是快速的Minor gc,所以长存区的可用空间依然是45%,这次回收的时间为384.469ms。在长存区发生的是Major gc,回收时间一般要长于Minor gc,所以健康的JVM 环境Minor gc:Minor gc=1:10(也不用太在意)。

在垃圾回收准备开始的那一段时间(time exclusiveaccessms),以及回收的过程中,另一个线程发现内存无法分配了,于是也要求一次gc过程,这时候就产生了gc队列(会有<warning details=”exclusive access time includes previous garbage collections” />显示)。一般前一次垃圾回收就会释放出足够这两次分配需要的空间,于是第二次gc过程就终止了,当然要是无法足够分配的话,马上就会再进行一次垃圾回收。不过这种情况下,估计要进行Full GC了。

Full GC的gc type就是global,这是stop the world的最耗费时间的回收方式,所以需要通过尽量调整参数来避免。如果发现不是由AF引起的,而是在开头写着SYS标签,那么就要好好问问开发,有没有使用System.gc()的必要?可以的话使用-Xdisableexplicitgc来禁止(Sun等JDK下为-XX:+DisableExplicitGC)。

以上所说的都是IBM JDK下垃圾回收日志的情况。在Sun和HP的JDK下情况相似,不过需要使用-XX:PrintHeapAtGC:参数来打印GC前后的详细堆栈信息。另外我建议加上-Xloggc:filename或者-Xverbosegclog:file_name(方便用工具分析)输出到特定文件,因为不知为何有时候会输出到native_stderr.log,或者在native_stdout.log中和thread dump夹杂在一起,不方便分析。

{Heap before GC invocations=116:
Heap
def new generation   total 157376K, used 139904K [63400000, 6dec0000, 78950000)
eden space 139904K, 100% used [63400000, 6bca0000, 6bca0000)
from space 17472K,   0% used [6bca0000, 6bca0000, 6cdb0000)
to   space 17472K,   0% used [6cdb0000, 6cdb0000, 6dec0000)
tenured generation   total 349568K, used 79067K [38800000, 4dd60000, 632b0000)
the space 349568K,  22% used [38800000, 3d536ce0, 3d536e00, 4dd60000)
compacting perm gen  total 132096K, used 132023K [28800000, 30900000, 38800000)
the space 132096K,  99% used [28800000, 308edf50, 308ee000, 30900000)
[GC 218971K->83116K(506944K), 0.0976948 secs]
Heap after GC invocations=117:
Heap
def new generation   total 157376K, used 4049K [63400000, 6dec0000, 78950000)
eden space 139904K,   0% used [63400000, 63400000, 6bca0000)
from space 17472K,  23% used [6cdb0000, 6d1a4628, 6dec0000)
to   space 17472K,   0% used [6bca0000, 6bca0000, 6cdb0000)
tenured generation   total 349568K, used 79067K [38800000, 4dd60000, 632b0000)
the space 349568K,  22% used [38800000, 3d536ce0, 3d536e00, 4dd60000)
compacting perm gen  total 132096K, used 132023K [28800000, 30900000, 38800000)
the space 132096K,  99% used [28800000, 308edf50, 308ee000, 30900000)
}

这是一个在使用HPJDK输出的实例,基本和IBM JDK没啥区别,可以加上-XX:+PrintGCTimeStamps显示每次回收的间隔。

这些“人肉”分析可以让我们清楚JVM运行的情况,但是还是不够直观,所以下次会介绍分析JVM日志的工具,尽情期待。现已完成,欢迎访问