以下是这些工具的SUN官方说明:
jps:http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jps.html
jstat:http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jstat.html
jmap:http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jmap.html
jconsole:http://java.sun.com/j2se/1.5.0/docs/guide/management/jconsole.html
JSTAT:工具说明--一个极强的监视VM内存工具。可以用来监视VM内存内的各种堆和非堆的大小及其内存使用量
接下来是jstat,我之所以这次调优Liferay portal是因为,liferay在默认的情况下,并发用户一多就会产生perm out of momery异常。虽然很开就解决了,但发现对VM内存使用量监控的重要性。通过google,很快的发现了jstat这个工具。
jstat工具特别强大,有众多的可选项,详细查看堆内各个部分的使用量,以及加载类的数量。使用时,需加上查看进程的进程id,和所选参数。以下详细介绍各个参数的意义。
jstat -class (KBytes ) pid:显示加载class的数量,及所占空间等信息。
jstat -compiler pid:显示VM实时编译的数量等信息。
jstat -gc pid((KB)): 可以显示gc的信息,查看gc的次数,及时间。其中最后五项,分别是young gc的次数,young gc的时间,full gc的次数,full gc的时间,gc的总时间。
jstat -gccapacity:可以显示,VM内存中三代(young,old,perm)对象的使用和占用大小,如:PGCMN显示的是最小perm的内存使 用量,PGCMX显示的是perm的内存最大使用量,PGC是当前新生成的perm内存占用量,PC是但前perm内存占用量。其他的可以根据这个类推, OC是old内纯的占用量。
jstat -gcnew pid:new对象的信息。
jstat -gcnewcapacity pid:new对象的信息及其占用量。
jstat -gcold pid:old对象的信息。
jstat -gcoldcapacity pid:old对象的信息及其占用量。
jstat -gcpermcapacity pid: perm对象的信息及其占用量。
jstat -util pid:统计gc信息统计。
jstat -printcompilation pid:当前VM执行的信息。
除了以上一个参数外,还可以同时加上 两个数字,如:jstat -printcompilation 3024 250 6是每250毫秒打印一次,一共打印6次,还可以加上-h3每三行显示一下标题。
jmap(jmap -heap pid可以看jvm参数使用状况)
观察运行中的jvm物理内存的占用情况。
参数如下:
-heap :打印jvm heap的情况
-histo: 打印jvm heap的直方图。其输出信息包括类名,对象数量,对象占用大小。
-histo:live : 同上,但是只答应存活对象的情况
-permstat: 打印permanent generation heap情况
命令使用:
jmap -heap 2083
可以观察到New Generation(Eden Space,From Space,To Space),tenured generation,Perm Generation的内存使用情况
输出内容:
jmap -histo 2083 | jmap -histo:live 2083
可以观察heap中所有对象的情况(heap中所有生存的对象的情况)。包括对象数量和所占空间大小。
输出内容:
jinfo:(看英文文档好像已经不怎么支持了)
的用处比较简单,就是能输出并修改运行时的java进程的运行参数。用法是jinfo -opt pid 如:查看2788的MaxPerm大小可以用 jinfo -flag MaxPermSize 2788。
jconsole
是一个用java写的GUI程序,用来监控VM,并可监控远程的VM,非常易用,而且功能非常强。由于是GUI程序,这里就不详细介绍了,不会的地方可以参考SUN的官方文档。
使用方法:命令行里打 jconsole,选则进程就可以了。下面是远程jconsole配置,在tomcat下加入
- catalina.bat: (windows 有set)
set JAVA_OPTS=%JAVA_OPTS% -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port="9004" -Dcom.sun.management.jmxremote.authenticate="false" -Dcom.sun.management.jmxremote.ssl="false"
- catalina.sh:(linux没有set)
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9004 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"
2)本机上使用jconsole连接远程的8999端口
报连接失败,检查网络情况,8999端口有在监听等待,本地机器能够连接上对端机器的8999端口。切换了一台linux机器,情况依旧。
3)去网上找了一把,发现一个网友一年多前也在为此苦恼,所不同的是网友用的是JDK1.5,我用的是JDK 1.6。该网文链接如下:
http://svr.wjworld.net/soft/P1558/I7132389.shtml
4)尝试抓包分析,发现是RMI的二进制协议,无法解读,报文中有127.0.0.1等字眼,从关键字判断是RMI下载的STUB文件。
5) 继续查找,发现了一篇有价值的文章谈到这个问题,是服务器端解释机器名的问题,如果服务器端hostname -i被定向到127.0.0.1则会出现连接失败的问题。修改/etc/hosts文件,使hostname -i 指向正确的IP,JConsole终于可以正常连接。
这篇文章链接如下:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6209663
6)可能的问题原因分析:JCONSOLE连接上监控的进程,从监控进程下载了RMI远程调用的STUB文件?该STUB访问服务器的进程,
服务器端的地址可能是通过hostname -i类似机制获得。
英文地址:
http://java.sun.com/javase/6/docs/technotes/tools/share/jstack.html
jstatd
启动jvm监控服务。它是一个基于rmi的应用,向远程机器提供本机jvm应用程序的信息。默认端口1099。
实例:jstatd -J-Djava.security.policy=my.policy
my.policy文件需要自己建立,内如如下:
grant codebase "file:$JAVA_HOME/lib/tools.jar" {
permission java.security.AllPermission;
};
这是安全策略文件,因为jdk对jvm做了jaas的安全检测,所以我们必须设置一些策略,使得jstatd被允许作网络操作
jps列出所有的jvm实例
列出本机所有的jvm实例
jps 192.168.0.77
列出远程服务器192.168.0.77机器所有的jvm实例,采用rmi协议,默认连接端口为1099
(前提是远程服务器提供jstatd服务)
输出内容如下:
jones@jones:~/data/ebook/java/j2se/jdk_gc$ jps
6286 Jps
6174 Jstat
jstack用来打印给定的jvm的线程的栈信息. 为每个java框架打印class全名,方法名,字节码地址,行号. 假如给定的jvm是运行在64位模式,那么你需要指定-J-d64参数,例如: jmap -J-d64 -heap pid
jstack在windows平台上,只能使用的形式如下:
jstack [-l] pid
jstack的命令形式:
jstack [ option ] pid
jstack [ option ] executable core
jstack [ option ] [server-id@]remote-hostname-or-IP
parameters
options
-F
当’jstack [-l] pid’没有相应的时候强制打印栈信息
-l
长列表. 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表.
-m
打印java和native c/c++框架的所有栈信息.
-h | -help
打印帮助信息
pid
需要被打印配置信息的java进程id,可以用jps查询.
executable
Java executable from which the core dump was produced.
(可能是产生core dump的java可执行程序)
core
将被打印信息的core dump文件
remote-hostname-or-IP
远程debug服务的主机名或ip
server-id
唯一id,假如一台主机上多个远程debug服务
以下是这些工具的SUN官方说明:
jps:http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jps.html
jstat:http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jstat.html
jmap:http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jmap.html
jconsole:http://java.sun.com/j2se/1.5.0/docs/guide/management/jconsole.html
附加:windows查看进程号,由于任务管理器默认的情况下是不显示进程id号的,所以可以通过如下方法加上。ctrl+alt+del打开任务管理器,选择‘进程’选项卡,点‘查看’->'选择列'->加上'PID',就可以了。
-----------------------------------------------------------------
JVM内存的设置的原理
默认的java虚拟机的大小比较小,在对大数据进行处理时java就会报错:java.lang.OutOfMemoryError。
设置jvm内存的方法,对于单独的.class,可以用下面的方法对Test运行时的jvm内存进行设置。
java -Xms64m -Xmx256m Test
-Xms是设置内存初始化的大小
-Xmx是设置最大能够使用内存的大小(最好不要超过物理内存大小)
在weblogic中,可以在startweblogic.cmd中对每个domain虚拟内存的大小进行设置,默认的设置是在commEnv.cmd里面。
本文引用地址: http://cnpoint.com/framwwork/2006/1109/content_4563.htm
JVM内存的调优
1. Heap设定与垃圾回收 Java Heap分为3个区,Young,Old和Permanent。Young保存刚实例化的对象。当该区被填满时,GC会将对象移到Old区。Permanent区则负责保存反射对象,本文不讨论该区。 JVM的Heap分配可以使用-X参数设定,
-Xms | 初始Heap大小 |
-Xmx | java heap最大值 |
-Xmn | young generation的heap大小 |
-Xss | 每个线程的 Stack 大小 |
当内存资源成为系统性能的瓶颈时,它有一些典型的症状:
很高的换页率(high pageout rate):通常情况下,它只执行调入页面进入内存的操作,以让进程能够运行。只有操作系统觉得系统需要释放一些内存空间时,才会执行从内存调出页面的操作,而过高的调出页面操作说明内存缺乏;
进 程进入不活动状态(process deactivation activity):当*的内存页面数量小于MINFREE时,很多进程将强制进入不活动状态,因为,any deactivation activity represents a condition in which normal paging is inadequate to handle the memory demands.
*内存的数量很小,但活动的虚拟内存却很大(very small free memory and large active virtual memory)
交换区所有磁盘的活动次数可高(high disk activity on swap devices)
可高的全局系统CPU利用率(high global system CPU utilization):
很长的运行进程队列,但CPU的空闲时间却很多(large run queue with idle CPU)
内存不够出错(out of memory errors)
CPU用于vhand和swapper两中守护进程的时间(CPU time to vhand and swapper)
必须注意的是,有时候我们发现CPU很忙,这似乎是CPU资源成为系统性能的瓶颈,但如果进一步分析,发现vhand和swapper守护进程占用了大量的系统CPU时间,很显然,这时系统性能瓶颈真正所在可能是内存。