当JVM响应变慢或者停滞的时候,我们往往需要对GC和其内存情况是进行分析,下面列举一些常用的分析方法和工具:
获得GC信息的方法
-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps
详细解释可以看JAVA SE 6 GC调优笔记
-XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStopped
-XX:+ PrintGCApplicationConcurrentTime
,打印在collection之间,程序运行的时间-XX:+ PrintGCApplicationStopped
,打印的是collection pause的时间
下面是这两个参数的输出样例:
Application time: 1.3874623 seconds
[GC [DefNew: 8064K->63K(8128K), 0.0509215 secs] 11106K->5994K(32704K), 0.0510972 secs]
Total time for which application threads were stopped: 0.0517092 seconds
Application time: 1.5225065 seconds
[GC [DefNew: 8127K->63K(8128K), 0.0432982 secs] 14058K->8273K(32704K), 0.0434172 secs]
Total time for which application threads were stopped: 0.0440447 seconds
Application time: 1.4263524 seconds
[GC [DefNew: 8127K->64K(8128K), 0.0363538 secs] 16337K->10381K(32704K), 0.0364811 secs]
Total time for which application threads were stopped: 0.0369103 seconds
从上面可以看出程序在minor collection之间跑了1.38到1.52秒,minor collection pause在.036到.051。所以minor collection的开销大致在2.6%到3.6%.
jstat
jstat的-option参数有很多种,输出的内容各不相同,详情参考官方文档
dump内存的方法
被动dump
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/dump.hprof
在OutOfMemory时,输出一个dump文件,记录当时的内存快照,并把文件输出到/tmp/dump.hprof文件
主动dump
利用jmap把内存dump下来,比如jmap -dump:live,format=b,file=dump.hprof
内存dump分析工具
jhat
Java内置工具(教程),dump文件少于1G的时候可以用这个,它会起一个web服务,用于查看dump信息。
需要有一台内存大于dump文件大小2倍的机器
HeapAnalyzer
直接分析dump并展示的客户端(下载)
需要有一台内存大于dump文件大小2倍的机器,还需要能显示出来的(桌面操作系)
mat
mat分为展示和分析模块,可以用一个ParseHeapDump.sh
先对dump文件分析并产生一堆索引文件(用服务器搞),然后再用mat的桌面应用打开这些文件,4G内存的机器分析8G的dump完全没压力。
如果你下的mat没有ParseHeapDump.sh
,可以自己添加一个:
#!/bin/sh
#
# This script parses a heap dump.
# Adjust the path to java, version 5 or later, and the heap size as required.
# Suitable for 64-bit and 32-bit Java, but a 64-bit Java is required
# for larger heap sizes.
#
# Usage: ParseHeapDump.sh <path/to/dump.dmp.zip> [report]*
#
# The leak report has the id org.eclipse.mat.api:suspects
# The top component report has the id org.eclipse.mat.api:top_components
#
java -Xmx8192M -jar "`dirname "$0"`"/plugins/org.eclipse.equinox.launcher_1*.jar -consoleLog -application org.eclipse.mat.api.parse "$@"
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。