jvm分析备忘

是什么
jps
  查看所有的jvm进程,包括进程ID,进程启动的路径等等。

jstack
  观察jvm中当前所有线程的运行情况和线程当前状态。
系统崩溃了?如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。
系统hung住了?jstack工具还可以附属到正在运行的java程序中,看到当时运行的java程序的java stack和native stack的信息, 如果现在运行的java程序呈现hung的状态,jstack是非常有用的。

jstat
  jstat利用JVM内建的指令对Java应用程序的资源和性能进行实时的命令行的监控,包括了对进程的classloader,compiler,gc情况;特别的,一个极强的监视内存的工具,可以用来监视VM内存内的各种堆和非堆的大小及其内存使用量,以及加载类的数量。

jmap
  监视进程运行中的jvm物理内存的占用情况,该进程内存内,所有对象的情况,例如产生了哪些对象,对象数量;
系统崩溃了?jmap 可以从core文件或进程中获得内存的具体匹配情况,包括Heap size, Perm size等等

jinfo
  观察进程运行环境参数,包括Java System属性和JVM命令行参数
系统崩溃了?jinfo可以从core文件里面知道崩溃的Java应用程序的配置信息


用法
jps
jps [options] [hostid] 如果不指定hostid就默认为当前主机或服务器。
    Jps -ml

jstack
-l long listings,会打印出额外的锁信息,在发生死锁时可以用jstack -l pid来观察锁持有情况
-m mixed mode,不仅会输出Java堆栈信息,还会输出C/C++堆栈信息(比如Native方法)
jstack可以定位到线程堆栈,根据堆栈信息我们可以定位到具体代码,所以它在JVM性能调优中使用得非常多。下面我们来一个实例找出某个Java进程中最耗费CPU的Java线程并定位堆栈信息,用到的命令有ps、top、printf、jstack、grep。
1. 第一步先找出Java进程ID (ps -ef|grep java |grep springWK –color=auto) 21711 
2.第二步找出该进程内最耗费CPU的线程,可以使用ps -Lfp pid或者ps -mp pid -o THREAD, tid, time或者top -Hp pid,我这里用第三个
TIME列就是各个Java线程耗费的CPU时间,CPU时间最长的是线程ID为21742的线程,用
printf “%x\n” 21742
得到21742的十六进制值为54ee
jstack 21711 | grep 54ee

jstat
具体参数如下:
-class:统计class loader行为信息 
-compile:统计编译行为信息 
-gc:统计jdk gc时heap信息 
-gccapacity:统计不同的generations(包括新生区,老年区,permanent区)相应的heap容量情况 
-gccause:统计gc的情况,(同-gcutil)和引起gc的事件 
-printcompilation:不知道干什么的,一直没用过。
一般比较常用的几个用法:
$ jstat -class 2840 1000 10 (每隔1秒监控一次,一共做10次) 
$ jstat -gc 2840 2000 20 (每隔2秒监控一次,共20次)
$ jstat -gcutil 2840 1000 10 (统计gc时,heap情况,按百分比显式) 
$ jstat -gccause 2840 1000 10 (统计gc的情况,(同-gcutil)和引起gc的事件,按百分比显式) 
$ jstat -compiler 2840 (显示VM实时编译的数量等信息) 
$ jstat -gccapacity 25917 (显示,VM内存中三代(young,old,perm)对象的使用和占用大小)
$ jstat -gcnew 25917(统计gc时,新生代的情况,new对象的信息)
$ jstat -gcnewcapacity 25917 (统计gc时,新生代heap容量 ,new对象的信息及其占用量)
$ jstat -gcold 25917 (统计gc时,老年区的情况,old对象的信息)
$ jstat -gcoldcapacity 25917 (统计gc时,老年区heap容量,old对象的信息及其占用量)
$ jstat -gcpermcapacity 25917 (统计gc时,permanent区heap容量,perm对象的信息及其占用量)
$ jstat -printcompilation -h3 25917 1000 5 (当前VM执行的信息,每1000毫秒打印一次,一共打印5次,还可以加上-h3每三行显示一下标题)
    一些术语的中文解释:
    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 : 最大持有次数限制


jmap
jmap -dump:format=b,file=dump.bin pid jmap 可以从core文件或进程中获得内存的具体匹配情况,包括Heap size, Perm size等等,目前只有在Solaris和Linux的JDK版本里面才有。
观察运行中的jvm物理内存的占用情况打印出某个java进程(使用pid)内存内的,所有‘对象’的情况(如:产生那些对象,及其数量)。可以输出所有内存中对象的工具,甚至可以将VM 中的heap,以二进制输出成文本。使用方法 jmap -histo pid。如果连用SHELL jmap -histo pid>a.log可以将其保存到文本中去,在一段时间后,使用文本对比工具,可以对比出GC回收了哪些对象。jmap -dump:format=b,file=String 3024可以将3024进程的内存heap输出出来到String文件里。如果带上live则只统计活对象.
$ jmap -histo:live 2840
    
还有一个很常用的情况是:用jmap把进程内存使用情况dump到文件中,可以用MAT、VisualVM等工具查看,这里用jhat查看分析
      jmap -dump:format=b,file=/tmp/dump.dat 21711 
      dump出来的文件可以用MAT、VisualVM等工具查看,这里用jhat查看
      jhat -port 9998 /tmp/dump.dat
      然后就可以在浏览器中输入主机地址:9998查看了


jinfo
可以输出并修改运行时的java 进程的opts。
如:
    查看运行时的参数 jinfo -flags 2840
    查看2788的MaxPerm大小可以用 jinfo -flag MaxPermSize 2788。
    参考范例
    JAVA_OPTS="-server -Xms4g -Xmx4g -XX:PermSize=96m -XX:MaxPermSize=256m -Xmn2560m -XX:SurvivorRatio=10 -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX
    :CMSMaxAbortablePrecleanTime=5000 -XX:+CMSClassUnloadingEnabled -XX:CMSInitiatingOccupancyFraction=80

jstatd
1.启动RMI服务
在需要被监控的服务器上面,通过jstatd来启动RMI服务 
首先,配置java安全访问,在服务器jdk路径(/java_home/bin)下新建文件 
名称: jstatd.all.policy 
内容:
grant codebase “file:${java.home}/../lib/tools.jar” {
permission java.security.AllPermission;
};
2.然后在进入jstatd.all.policy所在目录下,通过如下的命令启动RMI服务:
./jstatd -J-Djava.security.policy=jstatd.all.policy 
或者
./jstatd -J-Djava.security.policy=jstatd.all.policy -J-Djava.rmi.server.hostname=192.168.22.249

jdb
  jdb用来对core文件和正在运行的Java进程进行实时地调试,里面包含了丰富的命令帮助您进行调试,它的功能和Sun studio里面所带的dbx非常相似,但 jdb是专门用来针对Java应用程序的。用来对core文件和正在运行的Java进程进行实时地调试,里面包含了丰富的命令帮助您进行调试,它的功能和Sun studio里面所带的dbx非常相似,但 jdb是专门用来针对Java应用程序的。

    readOnly mode:
        $ jdb -connect sun.jvm.hotspot.jdi.SAPIDAttachingConnector:pid=9302

    debug mode:
        server add :
            -Dcom.sun.management.jmxremote.port=50199 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Xrunjdwp:transport=dt_socket,address=50100,server=y,suspend=y
        client:
            $jdb -attach 50100
            threads
            thread <thread_id>
            suspend <thread_id>
            step (等待)
            kill <thread_id> new java.lang.Exception()

        $ jdb -connect sun.jvm.hotspot.jdi.SACoreAttachingConnector:javaExecutable=$JAVA_HOME/bin/java,core=core.20441
        $ jdb -connect sun.jvm.hotspot.jdi.SADebugServerAttachingConnector:debugServerName=machine1


-----------------------------

jconsole
  jconsole是基于 (JMX)的实时图形化监测工具,这个工具利用了内建到JVM里面的JMX指令来提供实时的性能和资源的监控,包括了Java程序的内存使用,Heap size, 线程的状态,类的分配状态和空间使用等等。
与jstat相当。jconsole:一个java GUI监视工具,可以以图表化的形式显示各种数据。并可通过远程连接监视远程的服务器VM。用java写的GUI程序,用来监控VM,并可监控远程的VM,非常易用,而且功能非常强。命令行里打 jconsole,选则进程就可以了
 

 

posted @ 2016-09-09 16:16  Earic  阅读(637)  评论(0编辑  收藏  举报