您的位置:首页 > 编程语言 > Java开发

JVM监测和调试步骤(附jdk工具jps、jstat等常用工具说明和官方文档)

2011-05-07 18:03 671 查看
JVM调优步骤:
第一步:监测JVM(JavaVirtual Machine)/GC(Garbage Collector)
第二步:调优
一、监测JVM/GC
==========================以下段落摘自网络(google或百度均可查到)========================

jps:与unix上的ps类似,用来显示本地的java进程,可以查看本地运行着几个java程序,并显示他们的进程号。
jinfo:可以输出并修改运行时的java 进程的opts。
jstat:一个极强的监视VM内存工具。可以用来监视VM内存内的各种堆和非堆的大小及其内存使用量。
jmap:打印出某个java进程(使用pid)内存内的,所有‘对象’的情况(如:产生那些对象,及其数量)。
jconsole:一个java GUI监视工具,可以以图表化的形式显示各种数据。并可通过远程连接监视远程的服务器VM。

  jstat工具特别强大,有众多的可选项,详细查看堆内各个部分的使用量,以及加载类的数量。使用时,需加上查看进程的进程id,和所选参数。以下详细介绍各个参数的意义。

  jstat -class pid:显示加载class的数量,及所占空间等信息。
  jstat -compiler pid:显示VM实时编译的数量等信息。
  jstat -gc pid:可以显示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 -gcutil: 个人最喜欢用的,后面将详解。

  除了以上一个参数外,还可以同时加上 两个数字,如:jstat -printcompilation 3024 250 6是每250毫秒打印一次,一共打印6次,还可以加上-h3每三行显示一下标题。
  jmap是一个可以输出所有内存中对象的工具,甚至可以将VM 中的heap,以二进制输出成文本。使用方法 jmap -histo pid。如果连用SHELL jmap -histo pid>a.log可以将其保存到文本中去,在一段时间后,使用文本对比工具,可以对比出GC回收了哪些对象。jmap -dump:format=b,file=String 3024可以将3024进程的内存heap输出出来到String文件里。
  jinfo的用处比较简单,就是能输出并修改运行时的java进程的运行参数。用法是jinfo -opt pid 如:查看2788的MaxPerm大小可以用 jinfo -flag MaxPermSize 2788。
  jconsole是一个用java写的GUI程序,用来监控VM,并可监控远程的VM,非常易用,而且功能非常强。由于是GUI程序,这里就不详细介绍了,不会的地方可以参考SUN的官方文档。使用方法:命令行里打jconsole,选择进程就可以了。
使用jstat -gcutil 监控gc垃圾回收情况:

:~$ sudo jps
15734 WatchdogManager
15773 Resin
21947 Jps
:~$ sudo jstat -gcutil -t 15773 4s 50
Timestamp S0 S1 E O P YGC YGCT FGC FGCT GCT
5670.6 47.81 0.00 2.60 12.93 21.35 68 1.035 13 11.821 12.856
5674.7 47.81 0.00 6.65 12.93 21.35 68 1.035 13 11.821 12.856
5678.7 47.81 0.00 8.87 12.93 21.35 68 1.035 13 11.821 12.856
5682.7 47.81 0.00 10.35 12.93 21.35 68 1.035 13 11.821 12.856
5686.7 47.81 0.00 11.69 12.93 21.35 68 1.035 13 11.821 12.856
5690.7 47.81 0.00 14.15 12.93 21.35 68 1.035 13 11.821 12.856
5694.7 47.81 0.00 15.83 12.93 21.35 68 1.035 13 11.821 12.856
5698.7 47.81 0.00 17.07 12.93 21.35 68 1.035 13 11.821 12.856
5702.7 47.81 0.00 20.12 12.93 21.35 68 1.035 13 11.821 12.856
5706.6 47.81 0.00 23.22 12.93 21.35 68 1.035 13 11.821 12.856
5710.7 47.81 0.00 26.57 12.93 21.35 68 1.035 13 11.821 12.856
5714.7 47.81 0.00 29.78 12.93 21.35 68 1.035 13 11.821 12.856
5718.7 47.81 0.00 31.34 12.93 21.35 68 1.035 13 11.821 12.856
5722.7 47.81 0.00 33.45 12.93 21.35 68 1.035 13 11.821 12.856
5726.7 47.81 0.00 35.53 12.93 21.35 68 1.035 13 11.821 12.856
5730.7 47.81 0.00 37.80 12.93 21.35 68 1.035 13 11.821 12.856
5734.7 47.81 0.00 40.90 12.93 21.35 68 1.035 13 11.821 12.856
... ... ... ...

其中:
S0:Heap上的 Survivor space 0 段已使用空间的百分比
S1:Heap上的 Survivor space 1 段已使用空间的百分比
E: Heap上的 Eden space 段已使用空间的百分比
O: Heap上的 Old space 段已使用空间的百分比
P: Perm space 已使用空间的百分比
YGC:从程序启动到采样时发生Young GC的次数
YGCT:Young GC所用的时间(单位秒)
FGC:从程序启动到采样时发生Full GC的次数
FGCT:Full GC所用的时间(单位秒)
GCT:用于垃圾回收的总时间(单位秒)
针对上面的结果,稍微说说垃圾收集GC的基本操作过程如下:
  首先,GC把内存大体分成4块,分别是old generation(年老代),eden(年轻代),以及survivor space1(ss1),survivor space0(ss0)。
  当声明变量的时候,首先是把变量声明在年轻代中,然后当年轻代被填满,则发生次要垃圾收集,将其中存活对象复制到SS1中,再将年轻代清空。继续在eden中声明对象,当eden再次填满,则再次发生次要垃圾收集,这次是把ss1的内容计算存活期,如果很长就复制到年老代,其余的存活的复制到ss0,然后将ss1清空,并对eden进行前述的次要垃圾收集。 当年老代也被填满,则产生一次主要垃圾收集,非常耗费时间。
==================================================
附1:JDK1.6官方文档首页和以上工具集的帮助文档:
Java SE 6 Documentation:
http://download.oracle.com/javase/6/docs/index.html JDK Tools and Utilities(JDK工具和适用程序):
http://download.oracle.com/javase/6/docs/technotes/tools/index.html Monitoring Tools(监视工具):
jps - Java Virtual Machine Process Status Tool:
http://download.oracle.com/javase/6/docs/technotes/tools/share/jps.html jstat - Java Virtual Machine Statistics Monitoring Tool
http://download.oracle.com/javase/6/docs/technotes/tools/share/jstat.html Troubleshooting Tools(故障排除工具):
jinfo - Configuration Info
http://download.oracle.com/javase/6/docs/technotes/tools/share/jinfo.html jmap - Memory Map
http://download.oracle.com/javase/6/docs/technotes/tools/share/jmap.html Java Troubleshooting,Profiling,Monitoring and Management Tools(Java的故障排除,性能分析,监控和管理工具):
jconsole - Java Monitoring and Management Console
http://download.oracle.com/javase/6/docs/technotes/tools/share/jconsole.html 二、调优
========================= 以下段落摘自网络(google或百度均可查到) =========================
JVM参数详解以及配置调优

基本概念:
  PermGen space:全称是Permanent Generation space。就是说是永久保存的区域,用于存放Class和Meta信息,Class在被Load的时候被放入该区域。
  Heap space:存放Instance。GC(Garbage Collection)应该不会对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误。
  Java Heap分为3个区,Young,Old和Permanent。Young保存刚实例化的对象。当该区被填满时,GC会将对象移到Old区。Permanent区则负责保存反射对象。
JVM有2个GC线程:
  第一个线程负责回收Heap的Young区。
  第二个线程在Heap不足时,遍历Heap,将Young 区升级为Older区。Older区的大小等于-Xmx减去-Xmn,不能将-Xms的值设的过大,因为第二个线程被迫运行会降低JVM的性能。
为什么一些程序频繁发生GC?有如下原因:
  1) 程序内调用了System.gc()或Runtime.gc()。
  2) 一些中间件软件调用自己的GC方法,此时需要设置参数禁止这些GC。
  3) Java的Heap太小,一般默认的Heap值都很小。
  4) 频繁实例化对象,Release对象。此时尽量保存并重用对象,例如使用StringBuffer()和String()。
  如果你发现每次GC后,Heap的剩余空间会是总空间的50%,这表示你的Heap处于健康状态。许多Server端的Java程序每次GC后最好能有65%的剩余空间。
  建议Server端JVM最好将-Xms和-Xmx设为相同值。为了优化GC,最好让-Xmn值约等于-Xmx的1/3。一个GUI程序最好是每10到20秒间运行一次GC,每次在半秒之内完成。
  增加Heap的大小虽然会降低GC的频率,但也增加了每次GC的时间。并且GC运行时,所有的用户线程将暂停,也就是GC期间,Java应用程序不做任何工作。
  Heap大小并不决定进程的内存使用量。进程的内存使用量要大于-Xmx定义的值,因为Java为其他任务分配内存,例如每个线程的Stack等。
Stack的设定:
  每个线程都有他自己的Stack。
  -Xss 每个线程的Stack大小
  Stack的大小限制着线程的数量。如果Stack过大就会导致内存溢漏。-Xss参数决定Stack大小,例如-Xss1024K。如果Stack太小,也会导致Stack溢漏。
  硬件环境也影响GC的效率,例如机器的种类,内存,swap空间,和CPU的数量。
  如果你的程序需要频繁创建很多transient对象,会导致JVM频繁GC。这种情况你可以增加机器的内存,来减少Swap空间的使用。
4种GC:

第一种为单线程GC,也是默认的GC。该GC适用于单CPU机器。

第二种为Throughput GC,是多线程的GC,适用于多CPU,使用大量线程的程序。第二种GC与第一种GC相似,不同在于GC在收集Young区是多线程的,但在Old区和第一种一样,仍然采用单线程。-XX:+UseParallelGC参数启动该GC。

第三种为Concurrent Low Pause GC,类似于第一种,适用于多CPU,并要求缩短因GC造成程序停滞的时间。这种GC可以在Old区的回收同时,运行应用程序。-XX:+UseConcMarkSweepGC参数启动该GC。

第四种为Incremental Low Pause GC,适用于要求缩短因GC造成程序停滞的时间。这种GC可以在Young区回收的同时,回收一部分Old区对象。-Xincgc参数启动该GC。

部分JVM参数配置:
1、 heap size
a: -Xmx<n>
指定 jvm 的最大 heap 大小,如:-Xmx=2g
b: -Xms<n>
指定 jvm 的最小 heap 大小,如:-Xms=2g,高并发应用建议和-Xmx一样,防止因为内存收缩/突然增大带来的性能影响。
c: -Xmn<n>
指定 jvm 中 New Generation 的大小,如:-Xmn256m。 这个参数很影响性能,如果你的程序需要比较多的临时内存,建议设置到512M,如果用的少,尽量降低这个数值,一般来说128/256足以使用了。
d: -XX:PermSize=<n>
指定 jvm 中 Perm Generation 的最小值,如:-XX:PermSize=32m。 这个参数需要看你的实际情况,可以通过jmap 命令看看到底需要多少。
e: -XX:MaxPermSize=<n>
指定 Perm Generation 的最大值,如:-XX:MaxPermSize=64m
f: -Xss<n>
指定线程桟大小,如:-Xss128k,一般来说,webx框架下的应用需要256K。 如果你的程序有大规模的递归行为,请考虑设置到512K/1M。 这个需要全面的测试才能知道。不过,256K已经很大了。 这个参数对性能的影响比较大的。
g: -XX:NewRatio=<n>
指定 jvm 中 Old Generation heap size 与 New Generation 的比例,在使用 CMS GC 的情况下此参数失效,如:-XX:NewRatio=2
h: -XX:SurvivorRatio=<n>
指定 New Generation 中 Eden Space 与一个 Survivor Space 的 heap size 比例,-XX:SurvivorRatio=8,那么在总共New Generation为10m 的情况下,Eden Space为8m
i: -XX:MinHeapFreeRatio=<n>
指定 jvm heap在使用率小 n的情况下,heap进行收缩,Xmx==Xms 的情况下无效,如:-XX:MinHeapFreeRatio=30
j: -XX:MaxHeapFreeRatio=<n>
指定 jvm heap在使用率大于n的情况下,heap进行扩张,Xmx==Xms 的情况下无效,如:-XX:MaxHeapFreeRatio=70
k: -XX:LargePageSizeInBytes=<n>
指定 Java heap 的分页页面大小,如:-XX:LargePageSizeInBytes=128m
2: garbage collector
a: -XX:+UseParallelGC
指定在 New Generation 使用 parallel collector,并行收集,暂停app threads,同时启动多个垃圾回收thread,不能和 CMS gc 一起使用。系统吨吐量优先,但是会有较长长时间的app pause,后台系统任务可以使用此gc
b: -XX:ParallelGCThreads=<n>
指定 parallel collection 时启动的 thread 个数,默认是物理 processor 的个数。
c: -XX:+UseParallelOldGC
指定在 Old Generation 使用 parallel collector。
d: -XX:+UseParNewGC
指定在 New Generation 使用 parallel collector,是 UseParallelGC 的 gc 的升级版本,有更好的性能或者优点,可以和 CMS gc 一起使用。
e: -XX:+CMSParallelRemarkEnabled
在使用 UseParNewGC 的情况下,尽量减少 mark 的时间。
f: -XX:+UseConcMarkSweepGC
指定在 Old Generation 使用 concurrent cmark sweep gc,gc thread 和 app thread 并行 ( 在 init-mark 和 remark 时 pause app thread)。app pause 时间较短,适合交互性强的系统,如 web server。
g: -XX:+UseCMSCompactAtFullCollection
在使用 concurrent gc 的情况下,防止 memory fragmention,对 live object 进行整理,使 memory 碎片减少。
h: -XX:CMSInitiatingOccupancyFraction=<n>
指示在 old generation 在使用了 n% 的比例后,启动 concurrent collector,默认值是 68,如:-XX:CMSInitiatingOccupancyFraction=70。
i: -XX:+UseCMSInitiatingOccupancyOnly
指示只有在 old generation 在使用了初始化的比例后 concurrent collector 启动收集。
3、others
a: -XX:MaxTenuringThreshold=<n>
指定一个 object 在经历了 n 次 young gc 后转移到 old generation 区,在 linux64 的 java6 下默认值是 15,此参数对于 throughput collector 无效,如:-XX:MaxTenuringThreshold=31。
b: -XX:+DisableExplicitGC
禁止 java 程序中的 full gc,如 System.gc() 的调用. 最好加上么,防止程序在代码里误用了。对性能造成冲击。
c: -XX:+UseFastAccessorMethods
get,set 方法转成本地代码。
d: -XX:+PrintGCDetails
打应垃圾收集的情况如: [GC 15610.466: [ParNew: 229689K->20221K(235968K),0.0194460 secs] 1159829K->953935K(2070976K),0.0196420 secs]。
e: -XX:+PrintGCTimeStamps
打应垃圾收集的时间情况,如: [Times: user=0.09 sys=0.00,real=0.02 secs]。
f: -XX:+PrintGCApplicationStoppedTime
打应垃圾收集时,系统的停顿时间,如: Total time for which application threads were stopped: 0.0225920 seconds。
==================================================
附2:官方JVM参数说明文档
JavaTM Virtual Machine Technology(Java的虚拟机技术):
http://download.oracle.com/javase/6/docs/technotes/guides/vm/index.html Java HotSpot VM Options(Java HotSpot虚拟机选项):
http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: