JMAP、jstat命令详解

LesleeGolds 9年前

来自: http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=531464&id=2354636


显示java进程内存使用的相关信息

jmap pid #打印内存使用的摘要信息

jmap –heap pid #java heap信息

jmap -histo:live pid #统计对象count ,live表示在使用

jmap -histo pid >mem.txt #打印比较简单的各个有多少个对象占了多少内存的信息,一般重定向的文件

jmap -dump:format=b,file=mem.dat pid #将内存使用的详细情况输出到mem.dat 文件

 

用jhat命令可以参看 jhat  -J-Xmx512m mem.dat 

然后使用:http://127.0.0.1:7000/ 查看类相关信息 

 

各个className 

BaseType Character Type Interpretation

B byte signed byte

C char Unicode character

D double double-precision floating-point value

F float single-precision floating-point value

I int integer

J long long integer

L<classname>; reference an instance of class <classname>

S short signed short

Z boolean true or false

[ reference

one array dimension

 

内存泄漏一般都是有一定特征的,任何代码和数据都要占用内存,我简单总结内存泄漏的特征是内存占用不可控制,GC不可回收。我追踪内存使用量的曲线发现一些特征,在估计虚拟机即将崩溃时,使用

jmap -histo pid >mem.txt 发现相关内存泄漏的对象占用非常大比例的内存空间,然后很容易猜测问题大概的位置,一下子就解决了。

 

 

 Jstat是Sun JDK中自带的监控工具,利用了JVM内建的指令对Java应用程序的资源和性能进行实时的命令行的监控,包括了对Heap size和垃圾回收状况的监控等等。JStat是命令行方式运行,对系统资源占用很小,在大压力下很少影响性能。并且运行要求低,只要通过Telnet或SSH等方式远程登录到服务器所在机器,就可以进行监控。在与Jmap、JStack等工具结合使用时非常方便。

使用jstat命令监测如下内存使用和垃圾回收统计数据: 

$ <JDK>/bin/jstat –gcutil [-h<lines>] <pid> <interval>

jstat - gcutil选项打印所运行应用程序进程ID <pid>在指定抽样间隔<interval>下,堆使用及垃圾回收时间摘要,并且每<lines>行显示一次头信息。这产生出以下样例输出:

S0 S1 E O P YGC YGCT FGC FGCT GCT

0.00 0.00 24.48 46.60 90.24 142 0.530 104 28.739 29.269

0.00 0.00 2.38 51.08 90.24 144 0.536 106 29.280 29.816

0.00 0.00 36.52 51.08 90.24 144 0.536 106 29.280 29.816

0.00 26.62 36.12 51.12 90.24 145 0.538 107 29.552 30.090

一些术语的中文解释:

S0C:年轻代中第一个survivor(幸存区)的容量 (字节)

S1C:年轻代中第二个survivor(幸存区)的容量 (字节)

S0U:年轻代中第一个survivor(幸存区)目前已使用空间 (字节)

S1U:年轻代中第二个survivor(幸存区)目前已使用空间 (字节)

EC:年轻代中Eden(伊甸园)的容量 (字节)

EU:年轻代中Eden(伊甸园)目前已使用空间 (字节)

OC:Old代的容量 (字节)

OU:Old代目前已使用空间 (字节)

PC:Perm(持久代)的容量 (字节)

PU:Perm(持久代)目前已使用空间 (字节)

YGC:从应用程序启动到采样时年轻代中gc次数

YGCT:从应用程序启动到采样时年轻代中gc所用时间(s)

FGC:从应用程序启动到采样时old代(全gc)gc次数

FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s)

GCT:从应用程序启动到采样时gc用的总时间(s)

NGCMN:年轻代(young)中初始化(最小)的大小 (字节)

NGCMX:年轻代(young)的最大容量 (字节)

NGC:年轻代(young)中当前的容量 (字节)

OGCMN:old代中初始化(最小)的大小 (字节)

OGCMX:old代的最大容量 (字节)

OGC:old代当前新生成的容量 (字节)

PGCMN:perm代中初始化(最小)的大小 (字节)

PGCMX:perm代的最大容量 (字节)

PGC:perm代当前新生成的容量 (字节)

S0:年轻代中第一个survivor(幸存区)已使用的占当前容量百分比

S1:年轻代中第二个survivor(幸存区)已使用的占当前容量百分比

E:年轻代中Eden(伊甸园)已使用的占当前容量百分比

O:old代已使用的占当前容量百分比

P:perm代已使用的占当前容量百分比

S0CMX:年轻代中第一个survivor(幸存区)的最大容量 (字节)

S1CMX :年轻代中第二个survivor(幸存区)的最大容量 (字节)

ECMX:年轻代中Eden(伊甸园)的最大容量 (字节)

DSS:当前需要survivor(幸存区)的容量 (字节)(Eden区已满)

TT: 持有次数限制

MTT : 最大持有次数限制

如果FGC 过多,有必要调整下jvm参数

[root@yy8 bin]# jstat -gcutil 3821 5000  10

  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT   

  0.00   0.00 100.00  95.11  59.02    370   48.495   121  337.359  385.855

  0.00   0.00  84.36  99.99  59.03    370   48.495   122  345.393  393.888

  0.00  50.37 100.00  99.49  59.03    370   48.495   123  348.494  396.989

  0.00 100.00 100.00  56.58  59.03    371   48.496   124  348.494  396.989

  0.00   0.00  56.50  96.57  59.02    371   48.496   125  355.148  403.643

  0.00   0.00 100.00  96.57  59.02    372   48.496   126  355.148  403.643

  0.00   0.00  37.17  90.75  59.02    372   48.496   127  361.721  410.217

  0.00   0.00 100.00  90.75  59.02    373   48.496   128  361.721  410.217

5000 是5秒 ,10是10次

参考范例

JAVA_OPTS="-server -Xms4g -Xmx4g -XX:PermSize=96m -XX:MaxPermSize=256m -Xmn2560m -XX:SurvivorRatio=3 -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:

CMSMaxAbortablePrecleanTime=5000 -XX:+CMSClassUnloadingEnabled -XX:CMSInitiatingOccupancyFraction=80 -XX:+DisableExplicitGC -Djava.awt.headless=true -Dsun.net.client.defaultConnectTimeout=10000 -Dsun.net.client.defaultReadTimeout=30000"