最近有些空闲的时间,看了一些JVM内存管理方面的知识,由于JDK自带了一些工具用于Java的故障排除,性能分析,监控和管理等。从本章开始以及后续的文章将进行这方面的实践活动。
一、JDK监控类工具
注:文章中提及的工具均在java安装目录的/bin目录下
[1] jps -- Java Virtual Machine Process Status Tool
jvm进程状态工具,可以列出本机所有java进程的pid。该命令类似于linux的ps命令哦。
1.概要
jps [ options ] [ hostid ]
options
-q 禁止输出类的名称,JAR文件的名称,传递给方法的参数,主要产生本地VM标识符列表(即只输出pid列表);
-m 输出传递给main方法的参数,嵌入式JVM可能输出为空;
-l 输出应用程序主类的全包名或者应用程序jar文件的全路径名;
-v 输出传递给JVM的参数;
-V 输出通过flag文件传递到JVM中的参数(.hotspotrc文件或由-XX:Flags=<filename>指定的参数);
-Joption 传递参数到vm,例如:-J-Xms48m
hostid
[protocol:][[//]hostname][:port][/servername]
2.输出格式
lvmid [ [ classname | JARfilename | "Unknown"] [ arg* ] [ jvmarg* ] ]
3.示例
(1) jps 仅显示进程id,主类名
(2) jps -q 仅显示进程id
(3)jps -l 输出完全的包名,主类名,jar完全路径名
(4)jps -v 显示jvm参数(如果对jvm参数不熟悉,请看《深入JVM内幕》)
jps –l 127.0.0.1 输出127.0.0.1机器上的java进程,显示完全的包名,主类名,jar完全路径
注意:127.0.0.1主机要启动jstatd (关于如何启动jstatd,请参见jstated)
参考:
http://download.oracle.com/javase/6/docs/technotes/tools/share/jps.html
[2] Jstated --Virtual Machine jstat Daemon(虚拟机jstat守护进程)
jstatd工具是一个RMI服务器应用程序,用来监视Java虚拟机(JVM)的创建和终结,它提供了一个接口,允许远程监控工具连接到运行在本地主机上的JVM。
jstatd 服务需要本地存在一个RMI注册. jstatd服务将尝试依附于RMI注册,使用默认端口上,或者用-p指定的端口上. 假如rmi注册没有找到,jstatd应用将会创建一个使用指定端口或默认端口. 如果jstatd的参数指定了-nr选项,那么创建一个内部的RMI注册是被禁止的。
1.概要
jstatd [ options ]
options
-nr 当一个存在的RMI注册表未被找到时,jstatd将不试图创建一个内部的RMI注册表;
-p port 期望的RMI注册端口号,或者自己创建的RMI注册的端口号;
-n rminame 绑定在RMI注册表中的远程RMI对象的名称,默认为JstatRemoteHost;假如启动多个jstatd进程,那么就需要用这个参数指定名字以区分.
-Joption 传递参数到vm,例如:-J-Xms48m
2.securty
jstatd服务只能在合适的内部访问权限下启动. 因此jstatd进程必须用启动JVMs的同用户启动. 一些用户的权限,如root用户拥有该机所有JVMs的访问权限,可以启动jstatd,但是会引入额外的安全问题.jstatd服务没有为客户端提供任何验证. 所以他会把jstatd进程访问的jvms暴露给网络中所有的用户. 启动jstatd进程的时候需要考虑一下,你的网络是否安全,特别是在产品环境中.
在jstatd服务启动的时候引入一个policy文件将不会有任何安全的异常.
grant codebase "file:${java.home}/../lib/tools.jar" {
permission java.security.AllPermission;
};
将以上内容保存到名为jstatd.all.policy的当前目录文件中
然后启动jstatd
jstatd -J-Djava.security.policy=jstatd.all.policy
3.示例
(1)使用内部RMI注册表
jstatd -J-Djava.security.policy=jstatd.all.policy (默认端口为1099)
jps –l 127.0.0.1
(2)使用外部RMI注册表
rmiregistry 2020&
jstatd -J-Djava.security.policy=all.policy -p 2020
jps –l localhost:2020 (等价于远程监控访问)
参考:http://download.oracle.com/javase/6/docs/technotes/tools/share/jstatd.html[3] jstat - Java Virtual Machine Statistics Monitoring Tool
主要利用JVM内建的指令对Java应用程序的资源和性能进行实时的命令行的监控,包括了对Heap size和垃圾回收状况的监控。
概述
jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]
参数
generalOption(常规选项)
一个常规命令行选项(-help, -options, or -version)。如果你指定了常规选项中的一个,您就不能指定任何其他的选项或者参数。
outputOptions
一个或多个输出选项,由单一的statOption构成,加上-t、-h和-Joptions。
vmid
虚拟机标识符,一个指向目标jvm的字符串,一般语法如下:
[protocol:][//]lvmid[@hostname[:port]/servername]
Interval
采样间隔单位,秒(S)或毫秒(ms)。默认单位是毫秒,必须为正整数。
count
样品数量。默认值是无限的,必须为正整数。
generalOption详细说明
-help
显示帮助信息
-version
显示版本信息
-options
显示统计选项列表。参看后面的output options一节。
如果你未指定常规选型,那么你就可以指定输出选项了。输出选项确定jstat的输出内容和格式,并且由单一的statOption构成,再加上其它输出选项(- h,- t和- J)。statOption必须放在第一位。
输出的格式为表,列用空格隔开。带有标题的标题行用来描述列。使用-h来设置标题显示的频次。列标题名在不同的选项之间通常是一致的。通常情况下,如果两个选项提供具有相同名称的列,那么这两个列的数据源是相同的。
使用-t选项显示一个时间戳列,标注的时间戳将作为输出的第一列。当目标jvm启动后,时间戳列记录了消耗的时间,以秒来进行刻画。
使用间隔和计数参数,以确定jstat输出的频次和次数。
outputOptions详细说明
-statOption
class 类加载器行为信息的统计
compiler 编译器行为信息的统计;
gc 堆的垃圾收集行为信息的统计;
gccapacity 各代(新生代、旧生代、持久代)的容量以及它们相应空间信息的统计;
gccause 垃圾收集统计汇总(与 –gcutil相同),包括过去和当前垃圾收集事件的成因;
gcnew 对新生代行为信息的统计;
gcnewcapacity 对新生代的大小以及它们相应的空间的统计;
gcold 对旧生代以及持久代行为信息的统计;
gcoldcapacity 旧生代大小信息的统计;
gcpermcapacity 持久代大小信息的统计;
gctuil 垃圾收集统计汇总;
printcompilation 编译方法统计;
-h n
表示每n个样本(输出行)显示一个列标题,其中n是正整数,默认值是0。列标题要显示在上述样本数据的第一行中。
-t n
表示时间戳列作为输出的第一列。时间戳时间是自目标jvm开始的时间。
-JjavaOption
传递javaOption给java程序启动器。例如,-JXms48m 设置为48m的内存启动。
statOptions and Output
下列表格汇总了针对每个statOption的jstat输出的列;
-class 选项
列 |
描述 |
Loaded |
加载类的数量 |
Bytes |
加载的字节数 |
Unloaded |
卸载类的数量 |
Bytes |
卸载字节数 |
Time |
执行加载和卸载操作花费的时间 |
-compiler 选项
列 |
描述 |
Compiled |
执行的编译任务数量 |
Failed |
编译任务失败的数量 |
Invalid |
无效的编译任务的数量 |
Time |
执行编译任务所消耗的时间 |
FailedType |
最后编译失败的编译类型 |
FailedMethod |
最后编译失败的类名与方法 |
-gc 选项
列 |
描述 |
S0C |
新生代survibor space 0 区(S0)的容量(KB) |
S1C |
新生代survibor space 1 区(S1)的容量(KB) |
S0U |
S0使用(KB) |
S1U |
S1使用(KB) |
EC |
新生代Eden space容量(KB) |
EU |
Eden space使用(KB) |
OC |
旧生代的容量(KB) |
OU |
旧生代使用(KB) |
PC |
持久代容量(KB) |
PU |
持久代使用(KB) |
YGC |
从应用程序启动到采样时发生 Young GC 的次数 |
YGCT |
Young GC 所用的时间(单位秒) |
FGC |
Full GC 次数 |
FGCT |
Full GC 所用的时间(单位秒) |
GCT |
垃圾回收的总时间(单位秒) |
-gcutil 选项
列 |
描述 |
S0 |
Heap上Survivor space 0 区已使用空间的百分比 |
S1 |
Survivor space 1 区已使用空间的百分比 |
E |
Eden space 区已使用空间的百分比 |
O |
Old space 区已使用空间的百分比 |
P |
Perm space 区已使用空间的百分比 |
YGC |
从应用程序启动到采样时发生 Young GC 的次数 |
YGCT |
Young GC 所用的时间(单位秒) |
FGC |
Full GC 次数 |
FGCT |
Full GC 所用的时间(单位秒) |
GCT |
垃圾回收的总时间(单位秒) |
|
|
其他选项的输出,请查看reference
例子
(1)使用gc选项
在使用gc选项之前,首先要通过jps获得jvm的vmid,如下:
从图中可以看到,有3个java进程,2500是一个tomcat进程,tomcat对应一个jvm实例。
通过jstat –gc 2500我们能够看到如下信息,S0、S1、Eden space的容量以及使用量,旧生代、持久代的容量以及使用量,Younc GC和Full GC的次数以及GC的时间,GC总时间。
(2)使用gcutil
对vmid为2500的jvm进行采样,采样的数量为10,时间间隔为10秒。
从上图中我们看到,旧生代、持久代的使用率很高,尤其是持久代最高已经达到99.78%,因此,在内容容量许可的情况下,需要对heap的持久代以及旧生代的内存进行调整。
红色的框表示,在两次采样期间,JVM发生了3此Young GC,Survivor Space从56.41%降低到37.53%,Eden space由94.73%降低到10.63%。并且在GC期间,至少发生了一次从S1区到S0区的对象复制。
常驻内存区(P-持久代)的使用率,始终停留在99%左右,说明常驻内存没有突变,比较正常。如果young gc和full gc能够正常发生,而且都能有效回收内存,常驻内存区变化不明显,则说明java内存释放情况正常,垃圾回收及时,java内存泄露的几率就会大大降低。但也不能说明一定没有内存泄露。
posted on 2011-06-20 11:38
zhangxl 阅读(654)
评论(0) 编辑 收藏 所属分类:
java tools