JDK 中自带的 JAVA 命令行工具

Linux系统 gongyj 1531℃ 已收录 0评论

给一个系统定位问题的时候,知识、经验是关键基础,数据是依据,工具是运用知识处理数据的手段。这里的数据包括:运行日志、异常堆栈、GC日志、线程快照(threaddump/javacore文件)、堆转储快照(heapdump/hprof文件)等。经常使用适当的虚拟机监控和分析的工具可以加快我们分析数据和定位解决问题的速度,但我们在学习工具前,也应当意识到工具永远都是知识技能的一层包装,没有什么工具是“秘密武器”,学会了就能包医百病。

JAVA.png

JDK 是 Java 语言的软件开发工具包,没有它就无法编译 Java 程序。Java 开发人员肯定都知道 JDK 的 bin/ 目录下有“java”和“javac”这两个命令行工具,但并非所有程序员都了解过 JDK 的 bin/ 下其他命令行程序的作用。每逢 JDK 更新版本之时,bin/ 目录下命令行工具的数量和功能总会不知不觉地增加和增强。

在生产运行过程中最重要的工作莫过于监控与问题的处理,监控是预防问题产生很重要的手段。实现监控的手段非常多,有系统级别监控系统,也有许多监控小工具等等。JDK 中已提供了功能强大各种监控工具存放在 JDK 的 bin/ 目录下,bin/ 目录下如图:

jdk.png

下面就部分介绍这些工具的使用及作用。

一、jps —— 虚拟机进程状况工具

jps(JVM Process Status Tool)用来显示本地的 java 进程,以及进程号,进程启动的路径等。

JDK 的很多小工具的名称都参考了 Unix 命令的命名方式,jps(JVM Process Status Tool)是其中的典型。除了名字像 Unix 的 ps 命令外,功能也和 ps 类似:可以列出正在运行的虚拟机进程,并显示虚拟机执行主类(Main Class,main() 函数所在的类)的名称,以及这些进程的本地虚拟机的唯一ID(LVMID,Local Virtual Machine Identifier)。虽然功能比较单一,但它是使用频率最高的 JDK 命令行工具,因为其他 JDK 工具大多需要输入它查询到的 LVMID 来确定要监控的是哪一个虚拟机进程。对于本地虚拟机进程来说,LVMID 与操作系统的进程 ID(PID,Process Identifier)是一致的,使用 Windows 的任务管理器或 Unix 的 ps 命令也可以查询到虚拟机进程的 LVMID,但如果使用了多个虚拟机进程,无法根据进程名称定位时,那就只能依赖 jps 命令显示主类的功能区才能区分了。

用法提示:

usage: jps [-help]
       jps [-q] [-mlvV] [<hostid>]

Definitions:
    <hostid>:      <hostname>[:<port>]
    
-q    只输出LVMID,省略主类的名称    
-m    输出虚拟机进程启动时传递给主类的main()函数的参数    
-l    输出主类的全名,如果进程执行的是jar包,输出jar路径    
-v    输出虚拟机进程启动时JVM参数

1、显示运行中的Java进程:

[root@localhost ~]# jps
7563 Bootstrap
7349 Jps

2、显示进程 ID

[root@localhost ~]# jps -q
15779
7163

3、显示完整包名:

[root@localhost ~]# jps -l
7379 sun.tools.jps.Jps
7563 org.apache.catalina.startup.Bootstrap

4、输出Java进程的命令行输入参数:

[root@localhost ~]# jps -m
7395 Jps -m
7563 Bootstrap start

5、显示相应Java进程的完整的JVM参数:

[root@localhost ~]# jps -v
7484 Jps -Denv.class.path=.:/usr/local/jdk1.7.0_79/lib:/usr/local/jdk1.7.0_79/jre/lib:/usr/local/jdk1.7.0_79/lib/dt.jar:/usr/local/jdk1.7.0_79/lib/tools.jar -Dapplication.home=/usr/local/jdk1.7.0_79 -Xms8m
7563 Bootstrap -Dnop -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/usr/local/tomcat7/endorsed -Dcatalina.base=/usr/local/tomcat7 -Dcatalina.home=/usr/local/tomcat7 -Djava.io.tmpdir=/usr/local/tomcat7/temp

二、jinfo —— Java 配置信息工具

jinfo(Configuration Info for Java)的作用是实时地查看和调整虚拟机的各项参数。使用 jps 的命令的 -v 参数可以查看虚拟机启动时显示指定的参数列表,但如果想知道未被显示指定的参数的系统默认值,除了去找资料外,就只能使用 jinfo 的 -flag 选项进行查询了(如果只限于 JDK1.6 或以上版本的话,使用 java -XX:+PrintFlagsFinal 查看参数默认值也是一个很好的选择),jinfo 还可以使用 -sysprops 选项把虚拟机进程的System.getProperties() 的内容打印出来。这个命令在 JDK1.5 时期已经随着 Linux 版的 JDK 发布,当时只提供了信息查询的功能,JDK1.6 之后,jinfo 在 Windows 和 Linux 平台都有提供,并且加入了运行期修改参数的能力,可以使用 -flag[+|-]name 或 -flag name=valule 修改一部分运行期可写的虚拟机参数值。JDK1.6 中,jinfo 对于 Windows 平台的功能仍然有较大的限制,只提供了最基本的 -flag 选项。

jinfo 可观察运行中 java 程序的运行环境参数,参数包括 Java System 属性和 JVM 命令行参数;也可从 core 文件里面知道崩溃的 Java 应用程序的配置信息。
用法提示:

Usage:
    jinfo [option] <pid>
        (to connect to running process)
    jinfo [option] <executable <core>
        (to connect to a core file)
    jinfo [option] [server_id@]<remote server IP or hostname>
        (to connect to remote debug server)
where <option> is one of:
    -flag <name>         to print the value of the named VM flag
    -flag [+|-]<name>    to enable or disable the named VM flag
    -flag <name>=<value> to set the named VM flag to the given value
    -flags               to print VM flags
    -sysprops            to print Java system properties
    <no option>          to print both of the above
    -h | -help           to print this help message

首先,通过 jps 命令获取 Java 程序 Bootstrap 的进程号 7015

1、显示所有与该进程相关的信息,如下所示:

[root@localhost ~]# jinfo 7563
Attaching to process ID 7563, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.79-b02
Java System Properties:

java.runtime.name = Java(TM) SE Runtime Environment
java.vm.version = 24.79-b02
sun.boot.library.path = /usr/local/jdk1.7.0_79/jre/lib/amd64
shared.loader =
java.vendor.url = http://java.oracle.com/
java.vm.vendor = Oracle Corporation
path.separator = :
file.encoding.pkg = sun.io
java.vm.name = Java HotSpot(TM) 64-Bit Server VM
tomcat.util.buf.StringCache.byte.enabled = true

    ……(省略部分内容)

java.vendor = Oracle Corporation
catalina.base = /usr/local/tomcat7
file.separator = /
nop =
java.vendor.url.bug = http://bugreport.sun.com/bugreport/
common.loader = ${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar
sun.io.unicode.encoding = UnicodeLittle
sun.cpu.endian = little
package.access = sun.,org.apache.catalina.,org.apache.coyote.,org.apache.jasper.,org.apache.naming.resources.,org.apache.tomcat.
sun.cpu.isalist =

VM Flags:

-Dnop -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/usr/local/tomcat7/endorsed -Dcatalina.base=/usr/local/tomcat7 -Dcatalina.home=/usr/local/tomcat7 -Djava.io.tmpdir=/usr/local/tomcat7/temp

2、并不是所有信息都是我们需要的,我们可以添加“-flag jvm参数 pid”显示相应 jvm 参数信息,例如:

[root@localhost ~]# jinfo -flag MaxPermSize 7563
-XX:MaxPermSize=85983232
[root@localhost ~]# jinfo -flag PermSize 7563
-XX:PermSize=21757952
[root@localhost ~]# jinfo -flag LargePageSizeInBytes 7563
-XX:LargePageSizeInBytes=0
[root@localhost ~]# jinfo -flag AllowUserSignalHandlers 7563
-XX:-AllowUserSignalHandlers

JVM 具体有哪些参数他们的意义都是什么我会在 tomcat 调优中进行介绍。

三、jstat —— 虚拟机统计信息监控工具

jstat(JVM Statistics Monitoring Tool)是用于监控虚拟机各种运行状态信息的命令行工具。它利用了 JVM 内建的指令对 Java 应用程序的资源和性能进行实时的命令行的监控,包括了对 Heap size 和垃圾回收状况的监控等,可以显示本地或远程虚拟机进程中的类装载、内存、垃圾收集、JIT 编译等运行数据,在没有 GUI 图像界面,只提高了纯文本控制台环境的服务器上,它将是运行期定位虚拟机性能问题的首选工具。

用法提示:

Usage: jstat -help|-options
       jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

Definitions:
  <option>      选项,我们一般使用 -gcutil 查看gc情况
  
  <vmid>        对于命令格式中的VMID与LVMID需要特别说明下:如果是本地虚拟机进程,
                VMID和LVMID是一致的,如果是远程虚拟机进程,那VMID的格式应当是:
                [protocol:][//] lvmid [@hostname[:port]/servername]
                
  <lines>       Number of samples between header lines.
  <interval>    代表查询间隔,The following forms are allowed:
                    <n>["ms"|"s"]
                Where <n> is an integer and the suffix specifies the units as
                milliseconds("ms") or seconds("s"). The default units are "ms".
  <count>       代表查询间隔和次数,Number of samples to take before terminating.
  -J<flag>      Pass <flag> directly to the runtime system.

option代表这用户希望查询的虚拟机信息,主要分为3类:类装载、垃圾收集和运行期编译状况:

-class               监视类装载、卸载数量、总空间及类装载所耗费的时间,统计class loader行为信息   
-gc                  监视Java堆状况,包括Eden区、2个Survivor区、老年代、永久代等的容量,统计jdk gc时heap信息  
-gccapacity          监视内容与-gc基本相同,但输出主要关注Java 堆(heap)各个区域使用到的最大和最小空间   
-gcutil              监视内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比    
-gccause             与-gcutil功能一样,但是会额外输出导致上一次GC产生的原因    
-gcnew               监视新生代GC的状况    
-gcnewcapacity       监视内容与-gcnew基本相同,输出主要关注使用到的最大和最小空间,新生代heap容量   
-gcold               监视老年代GC的状况    
-gcoldcapacity       监视内容与-gcold基本相同,输出主要关注使用到的最大和最小空间,老年区heap容量   
-gcpermcapacity      输出永久代使用到的最大和最小空间,permanent区heap容量   
-compiler            输出JIT编译器编译过的方法、耗时等信息    
-printcompilation    输出已经被JIT编译的方法

1、统计 gc heap 情况,此选项是较常用的一个选项:

[root@localhost ~]#  jstat -gcutil 7563
  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT
  0.00  44.10  84.66  60.00  99.53    147    0.570     7    0.721    1.291

上面的命令没有刷新时间与刷新次数的参数,所以默认只打印出1行数据内容。

如果省略 interval 和 count 这两个参数,说明只查询一次。假设需要每 1000 毫秒查询一次进程 7563 垃圾收集状况,一共查询5次,那命令行如下:

[root@localhost ~]#  jstat -gcutil 7563 1000 5
  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT
  0.00  44.10  84.66  60.00  99.53    147    0.570     7    0.721    1.291
  0.00  44.10  84.66  60.00  99.53    147    0.570     7    0.721    1.291
  0.00  44.10  84.66  60.00  99.53    147    0.570     7    0.721    1.291
  0.00  44.10  84.66  60.00  99.53    147    0.570     7    0.721    1.291
  0.00  44.10  84.66  60.00  99.53    147    0.570     7    0.721    1.291

默认单位是ms,1000ms可以写成1s

#参数含义:
S0  — Heap上的 Survivor space 0 区已使用空间的百分比,里面都是空
S1  — Heap上的 Survivor space 1 区已使用空间的百分比,44.10%
E   — Heap上的 Eden space 区已使用空间的百分比,新生代 Eden 区使用了 84.66% 的空间
O   — Heap上的 Old space 区已使用空间的百分比,老年代 Old 区使用了 60.00% 的空间
P   — Perm space 区已使用空间的百分比,永久代 Permanent 区使用了99.53% 的空间
YGC — 从应用程序启动到采样时发生 Young GC 的次数,147 次
YGCT– 从应用程序启动到采样时 Young GC 所用的时间(单位秒),总耗时 0.570 秒
FGC — 从应用程序启动到采样时发生 Full GC 的次数,7 次
FGCT– 从应用程序启动到采样时 Full GC 所用的时间(单位秒) ,总耗时 0.721 秒
GCT — 从应用程序启动到采样时用于垃圾回收的总时间(单位秒),所有 gc 总耗时 1.291 秒

直接在控制台中使用 jstat 命令已然是一种常用的监控方式。

2、显示加载class的数量,及所占空间等信息:

[root@localhost ~]# jstat -class 7563
Loaded  Bytes  Unloaded  Bytes     Time
  2277  4700.2        0     0.0       1.65

3、显示VM实时编译的数量等信息:

[root@localhost ~]# jstat -compiler 7563
Compiled Failed Invalid   Time   FailedType FailedMethod
    1599      2       0    55.22          1 org/apache/tomcat/util/IntrospectionUtils setProperty

4、显示三代 heap 情况

gccapacity 可以显示 JVM 内存中三代(young,old,perm)对象的使用和占用大小,如:PGCMN 显示的是最小 perm 的内存使用量,PGCMX 显示的是 perm 的内存最大使用量,PGC 是当前新生成的 perm 内存占用量,PC 是但前 perm 内存占用量。其他的可以根据这个类推, OC 是 old 内存的占用大小。

[root@localhost ~]# jstat -gccapacity 7563
 NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC         OC      PGCMN    PGCMX     PGC       PC     YGC    FGC
 10688.0 171328.0  38464.0 3840.0 3840.0  30784.0    21440.0   342720.0    76820.0    76820.0  21248.0  83968.0  50368.0  50368.0    154     7

四、jstatd —— Java 后台统计监测

jstatd(Java Statistics Monitoring Daemon)是一个基于提供远程监控接口的 RMI(Remove Method Invocation,远程方法调用)的服务器程序,它用于监控基于 HotSpot 的 JVM 中资源的创建及销毁过程中资源占用情况,它是一个 Daemon 程序,要保证远程监控软件连接到本地的话需要 jstatd 始终保持运行,默认端口是 1099。

首先,我们可以在用户目录下的任何地方(比如说:用户根目录,或者是 JDK 根目录)新建一个名称为 my.policy 的文件,文件内容如下:

grant codebase  "file:${java.home}/../lib/tools.jar"  {  
 permission java.security.AllPermission;  
};

这是安全策略文件,因为 jdk 对 jvm 做了 jaas 的安全检测,所以我们必须设置一些策略,使得 jstatd 被允许作网络操作。

运行如下命令,启动jstatd服务

jstatd -J -Djava.security.policy=/usr/local/jdk1.7.0_79/my.policy

记住 my.policy 文件必须为绝对路径,防止出现 java.security.AccessControlException: access denied (java.util.PropertyPermission java.rmi.server.ignoreSubClasses write) 错误。

如果需要RMI 日志功能的话,还可以在启动参数中加入 -J-Djava.rmi.server.logCalls=true。

五、jmap —— Java内存映像工具

jmap(Memory Map for Java)命令可以直接观察运行中的 JVM 物理内存的占用情况,可用于生产堆转储快照(一般称为 heapdump 或 dump 文件)。如果不使用 jmap 命令,要向获取 Java 堆转储快照还有一些比较”暴力“的手段:譬如 -XX:+HeapDumpOnOutOfMemoryError 参数,可以让虚拟机在 OOM 异常出现之后自动生生成 dump 文件,通过 -XX:+HeapDumpOnCtrlBreak 参数则可以使用 [Ctrl]+[Break] 键让虚拟机生成 dump 文件,又或者在 Linux 系统下通过 Kill -3 命令发送进程退出信号”恐吓“一下虚拟机,也能拿到 dump 文件。

jmap 的作用并不仅仅是为了获取 dump 文件,它还可以查询 finalize 执行队列,Java 堆和永久代的详细信息,如空间使用率、当前用的是那种收集器等。除了生成 dump 文件的 -dump 选项和用于查看每个类的实例、空间占用统计的 -histo 选项,其余选项只能在 Linux/Solaris 下使用。

用法提示:

Usage:
    jmap [option] <pid>
        (to connect to running process)
    jmap [option] <executable <core>
        (to connect to a core file)
    jmap [option] [server_id@]<remote server IP or hostname>
        (to connect to remote debug server)

where <option> is one of:
    <none>               to print same info as Solaris pmap
    -heap                显示Java堆详细信息,如使用哪种回收器、参数配置、分代状况等。只在Linux/Solaris平台下有效
    -histo[:live]        打印jvm 堆的直方图。其输出信息包括类名,对象数量,对象占用大小。如果使用"live"参数则只显示存活对象的情况
    -permstat            以ClassLoader为统计口径显示永久代内存状态。只在Linux/Solaris平台下有效
    -finalizerinfo       显示在F-Queue中等待Finalizer线程执行finalize()方法的对象。只在Linux/Solaris平台下有效
    -dump:<dump-options> 生成Java堆转储快照。格式为:-dump:[live,]format=b,file=<filename>,pid
                         其中live子参数说明是否只dump出存活的对象
    -F                   force. Use with -dump:<dump-options> <pid> or -histo
                         to force a heap dump or histogram when <pid> does not
                         respond. The "live" suboption is not supported
                         in this mode.
    -h | -help           to print this help message
    -J<flag>             to pass <flag> directly to the runtime system

1、显示运行中Java进程:

[root@localhost ~]# jmap 7563
Attaching to process ID 7563, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.79-b02
0x0000000000400000      7K      /usr/local/jdk1.7.0_79/bin/java
0x0000003eecc00000      153K    /lib64/ld-2.12.so
0x0000003eed000000      22K     /lib64/libdl-2.12.so
0x0000003eed400000      1881K   /lib64/libc-2.12.so
0x0000003eed800000      142K    /lib64/libpthread-2.12.so
0x0000003eedc00000      46K     /lib64/librt-2.12.so
0x0000003eee000000      585K    /lib64/libm-2.12.so
0x0000003ef8800000      91K     /lib64/libgcc_s-4.4.7-20120601.so.1
0x00007f270069b000      36K     /usr/local/jdk1.7.0_79/jre/lib/amd64/headless/libmawt.so
0x00007f27008a2000      755K    /usr/local/jdk1.7.0_79/jre/lib/amd64/libawt.so
0x00007f270191f000      250K    /usr/local/jdk1.7.0_79/jre/lib/amd64/libsunec.so
0x00007f2701c67000      44K     /usr/local/jdk1.7.0_79/jre/lib/amd64/libmanagement.so
0x00007f27140a2000      112K    /usr/local/jdk1.7.0_79/jre/lib/amd64/libnet.so
0x00007f27142b9000      89K     /usr/local/jdk1.7.0_79/jre/lib/amd64/libnio.so
0x00007f271c2a0000      120K    /usr/local/jdk1.7.0_79/jre/lib/amd64/libzip.so
0x00007f271c4bb000      64K     /lib64/libnss_files-2.12.so
0x00007f271c6dd000      214K    /usr/local/jdk1.7.0_79/jre/lib/amd64/libjava.so
0x00007f271c908000      63K     /usr/local/jdk1.7.0_79/jre/lib/amd64/libverify.so
0x00007f271cc17000      14877K  /usr/local/jdk1.7.0_79/jre/lib/amd64/server/libjvm.so
0x00007f271da94000      103K    /usr/local/jdk1.7.0_79/lib/amd64/jli/libjli.so

2、显示 JVM 堆情况:

[root@localhost ~]# jmap -heap 7563
Attaching to process ID 7563, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.79-b02

using thread-local object allocation.
Mark Sweep Compact GC

Heap Configuration:
   MinHeapFreeRatio = 40
   MaxHeapFreeRatio = 70
   MaxHeapSize      = 526385152 (502.0MB)
   NewSize          = 1310720 (1.25MB)
   MaxNewSize       = 17592186044415 MB
   OldSize          = 5439488 (5.1875MB)
   NewRatio         = 2
   SurvivorRatio    = 8
   PermSize         = 21757952 (20.75MB)
   MaxPermSize      = 85983232 (82.0MB)
   G1HeapRegionSize = 0 (0.0MB)

Heap Usage:
New Generation (Eden + 1 Survivor Space):
   capacity = 37617664 (35.875MB)
   used     = 7861992 (7.497779846191406MB)
   free     = 29755672 (28.377220153808594MB)
   20.899734762902874% used
Eden Space:
   capacity = 33488896 (31.9375MB)
   used     = 7861992 (7.497779846191406MB)
   free     = 25626904 (24.439720153808594MB)
   23.476414391205967% used
From Space:
   capacity = 4128768 (3.9375MB)
   used     = 0 (0.0MB)
   free     = 4128768 (3.9375MB)
   0.0% used
To Space:
   capacity = 4128768 (3.9375MB)
   used     = 0 (0.0MB)
   free     = 4128768 (3.9375MB)
   0.0% used
tenured generation:
   capacity = 83439616 (79.57421875MB)
   used     = 47624176 (45.41795349121094MB)
   free     = 35815440 (34.15626525878906MB)
   57.076216649894455% used
Perm Generation:
   capacity = 52756480 (50.3125MB)
   used     = 52510376 (50.077796936035156MB)
   free     = 246104 (0.23470306396484375MB)
   99.5335094380823% used

23421 interned Strings occupying 2740360 bytes.

3、显示JVM资源直方图:

[root@localhost ~]# jmap -histo 7563

 num     #instances         #bytes  class name
----------------------------------------------
   1:         33516       15937240  [B
   2:        119451       15382288  [C
   3:         90487       13768640  <constMethodKlass>
   4:         90487       11593360  <methodKlass>
   5:          8226        9891888  <constantPoolKlass>
   6:          8226        6022464  <instanceKlassKlass>
   7:          6806        5537536  <constantPoolCacheKlass>
   8:        113623        2726952  java.lang.String
   
   ……(省略部分内容)

3568:             1             16  sun.reflect.GeneratedMethodAccessor15
3569:             1             16  sun.reflect.generics.tree.ByteSignature
3570:             1             16  com.sun.org.apache.xerces.internal.impl.dv.xs.PrecisionDecimalDV
3571:             1             16  org.apache.catalina.valves.AccessLogValve$1
3572:             1             16  net.sf.json.processors.JsonValueProcessorMatcher$DefaultJsonValueProcessorMatcher
3573:             1             16  java.security.ProtectionDomain$1
Total        976531      104212256

4、 将dump信息保存至heap.bin中

[root@localhost ~]# jmap -dump:format=b,file=heap.bin 7563
Dumping heap to /root/heap.bin ...
Heap dump file created

可以用 jhat 分析或 在eclipse中安装MAT插件(http://www.eclipse.org/mat/ ), 然后在eclipse中,file—->open,打开这个文件 heap.bin,利用现成的 OOM 工具进行分析。

六、jhat —— 虚拟机堆转储快照分析工具
jhat(JVM Heap Analysis Tool)用来解析和浏览堆文件。jhat 内置了一个微型的 HTTP/HTML 服务器,生成 dump 文件的分析结果后,可以在浏览器中查看,不过实事求是地说,在实际工作中,除非真的没有别的工具可用,否则一般不会去直接使用 jhat 命令来分析 dump 文件,主要原因有二:意识一般不会在部署应用程序的服务器上直接分析 dump 文件,即使可以这样做,也会尽量将 dump 文件拷贝到其他机器上进行分析,因为分析工作时一个耗时且消耗硬件资源的过程,既然都要在其他机器上进行,就没必要收到命令行工具的限制了。另外一个原因是 jhat 的分析功能相对来说很简陋,VisualVM 以及专门分析 dump 文件的 Eclipse Memory Analyzer、IBM HeapAnalyzer 等工具,都能实现比 jhat 更强大更专业的分析功能。

[root@localhost ~]# jhat heap.bin
Reading from heap.bin...
Dump file created Wed Oct 7 10:46:33 CST 2015
Snapshot read, resolving...
Resolving 144125 objects...
Chasing references, expect 28 dots............................
Eliminating duplicate references............................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.

"Server is ready."出现后就可以在浏览器中键入http://localhost:7000 查看分析堆转储的详细情况了。分析结果默认以包为单位进行分组显示,分析内存泄露问题主要会使用到其中的”Heap Histogram“(与jmap-hosto功能一样)与OQL页签的功能。前者可以找到内存总容量最大的对象,后者是标准的对象查询语句,使用类似SQL的语法对内存中的对象进行查询统计。

七、jstack —— Java堆栈跟踪工具

jstack(Stack Trace for Java)命令用于生成虚拟机当前时刻的线程快照(一般称为threaddump或javacore文件)。线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等都是导致线程长时间停顿的常见原因。线程出现停顿的时候通过 jstack 来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做些什么事情,或者等待着什么资源。

用法提示:

Usage:
    jstack [-l] <pid>
        (to connect to running process)
    jstack -F [-m] [-l] <pid>
        (to connect to a hung process)
    jstack [-m] [-l] <executable> <core>
        (to connect to a core file)
    jstack [-m] [-l] [server_id@]<remote server IP or hostname>
        (to connect to a remote debug server)

Options:
    -F  当正常输出的请求不被响应时,强制输出线程堆栈
    -m  如果调用到本地方法的话,可以显示C/C++的堆栈
    -l  除堆栈外,显示关于锁的附加信息
    -h or -help to print this help message
[root@localhost ~]# jstack -l 7563
   ……(省略)

八、其它命令行工具

jar — 打包与解包。

jarsigner — 制作签名文件与验证签名。

javac — java 语言编程编译器。

javah — 用于在 JNI 开发的时,把java代码声明的 JNI 方法转化成 C\C++ 头文件,以便进行 JNI 的 C\C++ 端程序的开发。

javap — 反汇编器,可以查看 java 编译器为我们生成的字节码。

jcontrol — java 控制面板。

jconsole — 是一个基于 JMX 的 GUI 监控工具,用于连接正在运行的 JVM,不过此 JVM 需要使用可管理的模式启动。

jrunscript — 可以执行 JavaScript 脚本,在 JDK 1.6 开始引入。

rmic — java 中 rmi(remote method invoke)的编译命令,rmic 编译的时候跟 javac 不一样,类名一定要写全,比如:rmic com.aa.bb.Test。而且文件名后面不能有 .class。还有这个 class 一定要放在 classpath 下。

jcmd — 它是一个多功能工具,可以用来导出堆,查看 java 进程,导出线程信息,执行 GC 等,在 JDK 1.7 之后引入。jcmd 拥有 与 jmap 的大部分功能,并且 Oracle 官方也建议使用 jcmd 代替 jmap,也可代替 jps 工具。jcmd <pid> [help]

jmc —  也是一个基于 JMX 的 GUI 监控工具,在 JDK1.7及以上,仅有Oracle jdk,Oracle公司已经将jrmc改造为jmc工具,也只有 jconsole 和 jmc 工具可以使用。

jvisualvm — 也是一个基于 JMX 的 GUI 监控和分析工具,自从 JDK 6 Update 7 以后已经作为 JDK 的一部分。

暂时就介绍这些,以后再详细的介绍这些工具的使用,JDK 自带工具一览表可参考:http://www.softown.cn/post/168.html

八、一些术语的中文解释
  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 : 最大持有次数限制

本站文章如未注明,均为原创丨本网站采用BY-NC-SA协议进行授权,转载请注明转自:http://blog.chopmoon.com/favorites/225.html
喜欢 (1)
发表我的评论
取消评论

表情 代码 贴图 加粗 链接 私信 删除线 签到

Hi,请填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
正在加载中……