提纲
JDK的命令行工具
1.进程状况查看工具
- jps -l输出主类的全名
- Jps -q省略主类的名称
- Jps -m输出进程启动时传递给主类main()函数的参数
- Jps -v输出进程启动时jvm的参数
2.虚拟机统计信息监视工具
jstat [ option vmid [interval(查询间隔)[s|ms] [count(次数)]] ]
例:
C:\Users\lenovo>jstat -class 18704 250 5(监视类装载Loaded、卸载数量Unloaded、总空间以及类装载所耗费的时间Time)
Loaded Bytes Unloaded Bytes Time
21617 46751.3 30 46.8 144.20
21617 46751.3 30 46.8 144.20
21617 46751.3 30 46.8 144.20
21617 46751.3 30 46.8 144.20
21617 46751.3 30 46.8 144.20
C:\Users\lenovo>jstat -gc 18704 250 20(监视java堆情况,包括Eden区、两个survivor区、老年代、永久代的容量、已用空间、gc时间合计等信息。)
S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGC FGCT GCT
31744.0 512.0 0.0 0.0 229376.0 83.0 349696.0 230084.0 187904.0 133283.5 45 1.144 11 7.977 9.121
C:\Users\lenovo>jstat -gccapacity 18704 250 2(输出主要关注java堆各个区域使用到的最大最小空间)
NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC PGCMN PGCMX PGC PC YGC FGC
175104.0 349696.0 286720.0 27648.0 28672.0 229376.0 349696.0 698880.0 349696.0 349696.0 21504.0 262144.0 167936.0 167936.0 48 14
175104.0 349696.0 286720.0 27648.0 28672.0 229376.0 349696.0 698880.0 349696.0 349696.0 21504.0 262144.0 167936.0 167936.0 48 14
C:\Users\lenovo>jstat -gcutil 18704 250 2(输出主要关注已使用空间站总空间的百分比)
S0 S1 E O P YGC YGCT FGC FGCT GCT
0.00 0.00 0.37 57.38 81.83 49 1.218 15 10.599 11.817
0.00 0.00 0.37 57.38 81.83 49 1.218 15 10.599 11.817
C:\Users\lenovo>jstat -gccause 18704 250 2(额外输出导致上一次gc产生的原因)
S0 S1 E O P YGC YGCT FGC FGCT GCT LGCC GCC
0.00 0.00 0.51 57.38 81.83 49 1.218 15 10.599 11.817 System.gc() No GC
0.00 0.00 0.51 57.38 81.83 49 1.218 15 10.599 11.817 System.gc() No GC
C:\Users\lenovo>jstat -gcnew 18704 250 2监视新生代
S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT
27136.0 1024.0 0.0 0.0 1 15 27136.0 229376.0 1168.8 49 1.218
27136.0 1024.0 0.0 0.0 1 15 27136.0 229376.0 1168.8 49 1.218
C:\Users\lenovo>jstat -gcnewcapacity 18704 250 2
NGCMN NGCMX NGC S0CMX S0C S1CMX S1C ECMX EC YGC FGC
175104.0 349696.0 281600.0 116224.0 25088.0 116224.0 26112.0 348672.0 229376.0 50 16
175104.0 349696.0 281600.0 116224.0 25088.0 116224.0 26112.0 348672.0 229376.0 50 16
C:\Users\lenovo>jstat -gcold 18704 250 2监视老年代
PC PU OC OU YGC FGC FGCT GCT
158208.0 133229.8 349696.0 200472.1 50 16 10.943 12.179
158208.0 133229.8 349696.0 200472.1 50 16 10.943 12.179
C:\Users\lenovo>jstat -gcoldcapacity 18704 250 2
OGCMN OGCMX OGC OC YGC FGC FGCT GCT
349696.0 698880.0 349696.0 349696.0 50 16 10.943 12.179
349696.0 698880.0 349696.0 349696.0 50 16 10.943 12.179
C:\Users\lenovo>jstat -gcpermcapacity 18704 250 2输出永久代的最大、最小使用空间
PGCMN PGCMX PGC PC YGC FGC FGCT GCT
21504.0 262144.0 158208.0 158208.0 50 16 10.943 12.179
21504.0 262144.0 158208.0 158208.0 50 16 10.943 12.179
C:\Users\lenovo>jstat -compiler 18704 250 2输出jit编译器编译过的方法、耗时信息
Compiled Failed Invalid Time FailedType FailedMethod
3541 1 0 65.49 1 com/google/inject/spi/InjectionPoint getInjectionPoints
3541 1 0 65.49 1 com/google/inject/spi/InjectionPoint getInjectionPoints
C:\Users\lenovo>jstat -printcompilation 18704 250 2输出已经被jit编译过的方法
Compiled Size Type Method
3541 79 1 org/eclipse/swt/widgets/Display checkDevice
3541 79 1 org/eclipse/swt/widgets/Display checkDevice
3.Java配置信息工具:jinfo
Usage:
jinfo [option] <pid>
(连接正在运行的进程)
jinfo [option] <executable <core>
(连接可运行的核心文件)
jinfo [option] [server_id@]<remote server IP or hostname>
(连接远程的)
where <option> is one of:option可以为以下信息
-flag <name> 打印指定jvm的参数值
-flag [+|-]<name> 设置指定jvm参数的布尔值
-flag <name>=<value> 设置指定jvm参数的值
-flags 打印所有jvm参数
-sysprops 打印系统属性
<no option> 打印所有信息
-h | -help to print this help message
4.Java内存映像工具:jmap
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> 打印与Solaris pmap相同的信息
-heap 打印java堆摘要
-histo[:live] 打印Java对象统计信息;如果指定“活”子选项,则只计数活动对象
-permstat 打印永久代生成的统计数据
-finalizerinfo 打印关于在finaizer队列中的对象的信息
-dump:<dump-options> 以hprof二进制格式转储java堆
dump-options:
live 仅转储活动对象;如果没有指定,堆中的所有对象都被存储。
format=b binary format
file=<file> dump heap to<file>
Example: jmap-dump:live,format=b,file=heap.bin <pid>
-F 强制。与-dump:<dump-options> <pid>或-histo一起使用以在<pid>不响应时强制堆转储或直方图。 “实时”子选项不受支持
in this mode.
-h | -help to print this help message
-J<flag> 将<flag>直接传递给运行时的系统
示例--打印对象统计信息:
示例--输出堆快照
示例--打印finalizer队列中的信息
5.虚拟机堆转出快照分析工具:Jhat
Usage: jhat [-stack <bool>] [-refs<bool>] [-port <port>] [-baseline <file>] [-debug<int>] [-version] [-h|-help] <file>
-J<flag> 直接将<flag>传递给运行时系统。例如,-J-mx512m的最大堆大小为512MB
-stack false: 关闭跟踪对象分配调用堆栈。
-refs false: 关闭跟踪对象的引用
-port <port>: 设置HTTP服务器的端口。默认为7000
-exclude <file>: 指定一个文件,列出应该从查询中可访问的地方排除的数据成员。
-baseline <file>: 指定一个基线对象转储。具有相同ID和相同类的堆转储中的对象将被标记为不是“新”。
-debug <int>: 设置调试级别
0: 没有调试输出
1: 调试hprof文件解析
2: 调试hprof文件解析,不需要服务器
-version 报告版本号
-h|-help Print this help and exit
<file> 要读取的文件
示例--分析堆快照
登陆localhost:7000,使用OQL或者其他工具进行查看
6.Java对栈跟踪工具:Jstack
Usage:
jstack [-l] <pid>
(to connect to running process)
jstack -F [-m] [-l] <pid>
(连接到一个挂起的进程)
jstack [-m] [-l] <executable><core>
(to connect to a core file)
jstack [-m] [-l] [server_id@]<remoteserver IP or hostname>
(to connect to a remote debug server)
Options:
-F 强制线程转储。在jstack <pid>不响应时使用(进程挂起)
-m 打印java和本机帧(混合模式)
-l 详细信息。打印有关锁定的其他信息
-h or -help to print this help message
示例--jstack查看堆栈信息
package chapter6;
import java.util.concurrent.locks.ReentrantLock;
public class DeadLock extends Thread {
protected Object myDirect;
static ReentrantLock south = new ReentrantLock();
static ReentrantLock north = new ReentrantLock();
public DeadLock(Object myDirect) {
super();
this.myDirect = myDirect;
if(this.myDirect==south){
this.setName("south");
}
if(this.myDirect==north){
this.setName("north");
}
}
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
if(myDirect==south){
try {
north.lockInterruptibly();
Thread.sleep(500);
south.lockInterruptibly();
System.out.println("car to south has passed");
} catch (InterruptedException e) {
System.out.println("car to south is killed");
}finally{
if(north.isHeldByCurrentThread())
north.unlock();
if(south.isHeldByCurrentThread())
south.unlock();
}
}
if(myDirect==north){
try {
south.lockInterruptibly();
Thread.sleep(500);
north.lockInterruptibly();
System.out.println("car to north has passed");
} catch (InterruptedException e) {
System.out.println("car to north is killed");
}finally{
if(north.isHeldByCurrentThread())
north.unlock();
if(south.isHeldByCurrentThread())
south.unlock();
}
}
}
public static void main(String[] args) throws InterruptedException {
DeadLock car2south = new DeadLock(south);
DeadLock car2north = new DeadLock(north);
car2south.start();
car2north.start();
Thread.sleep(1000);
}
}
输入命令行,新查询对应的pid。
查看结果:
6.远程主机信息收集:jstatd
将本地jvm作为服务器向远程开放。直接打开时,创建失败:
新建文本文档并编辑:
重新运行:
查看开启的RMI服务器:
显示远程计算机的java进程
查看远程进程中Main的gc情况:
7.多功能命令行:jcmd
Usage: jcmd <pid | main class> <command ...|PerfCounter.print|-f file>
or: jcmd -l
or: jcmd -h
命令必须是所选jvm的有效jcmd命令。
使用命令“help”查看哪些命令可用。
如果pid为0,则命令将被发送到所有Java进程。
主类参数将用于匹配(部分地)
或完全)用于启动Java的类。
如果没有给出选项,则列出Java进程(与-p相同)。
PerfCounter.print显示此进程公开的计数器
-f 从文件读取并执行命令
-l 列出本地机器上的JVM进程
-h this help
8.性能统计工具-hprof
hprof usage: java -agentlib:hprof=[help]|[<option>=<value>, ...]
Option Name and Value Description Default
--------------------- ----------- -------
heap=dump|sites|all 堆分析 all
cpu=samples|times|old CPU usage off
monitor=y|n 监视争用 n
format=a|b text(txt) or binary output a
file=<file> 将数据写入文件 java.hprof[{.txt}]
net=<host>:<port> 通过套接字发送数据 off
depth=<size> 堆栈跟踪深度 4
interval=<ms> 采样间隔以毫秒为单位 10
cutoff=<value> output cutoff point 0.0001
lineno=y|n line number in traces? y
thread=y|n thread in traces? n
doe=y|n dump on exit? y
msa=y|n Solaris micro state accounting n
force=y|n force output to <file> y
verbose=y|n print messages about dumps y
Obsolete Options
----------------
gc_okay=y|n
示例--使用hprof统计性能信息
package chapter6;
//去掉包名运行
public class HprofTest {
public void slowMethod(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void slowerMethod(){
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void fastMethod(){
try{
Thread.yield();
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) {
HprofTest test = new HprofTest();
test.fastMethod();
test.slowMethod();
test.slowerMethod();
}
}
结果:
7.JIT生成代码反汇编:HSDIS
引用并参考:在64位Windows上编译hsdis_yizishou的博客-CSDN博客_hsdis-amd64.dylib
步骤:
1.下载安装Cygwin;
进入select包时,安装如下包:
- Devel - make
- Devel - gcc-core
- Devel - mingw64-x86_64-gcc-core
- Utils - diffutils
2.下载beanutil与openjdk源码,并复制到如下目录
openjdk下载步骤:tags——>相应版本—>bz2
- 将下载的binutils、openJDK源码/src/share/tools/hsdi解压到~下
- 修改~/hsdis/Makefile文件,搜索LIBRARIES,将
LIBRARIES = $(TARGET_DIR)/bfd/libbfd.a \
$(TARGET_DIR)/opcodes/libopcodes.a \
$(TARGET_DIR)/libiberty/libiberty.a
修改为
LIBRARIES = $(TARGET_DIR)/bfd/libbfd.a \
$(TARGET_DIR)/zlib/libz.a \
$(TARGET_DIR)/opcodes/libopcodes.a \
$(TARGET_DIR)/libiberty/libiberty.a
保存 - 在Cygwin窗口输入cd ~/hsdis,然后输入命令make OS=Linux MINGW=x86_64-w64-mingw32 'AR=$(MINGW)-ar' BINUTILS=~/binutils-2.27(最后的binutils路径需要与实际安装路径一致)
- 编译完,hsdis-amd64.dll现在就在~/hsdis/build/Linux-amd64里面了,把它复制到$JAVA_HOME/jre/bin/server(或$JAVA_HOME/jre/bin/client下面。
示例:
package hsdis;
/**
* HSDIS:JIT生成反代码汇编
* java -XX:+UnlockDIagnosticVMOptions -XX:+PrintAssembly
* -Xcomp -XX:CompileCommand=dontinline,*Bar.sum
* -XXCompileCommand=compileonly,*Bar.sum hsdis.Bar
* @author shiker
*
*/
public class Bar {
int a=1;
static int b=2;
public int sum(int c){
return a+b+c;
}
public static void main(String[] args) {
new Bar().sum(3);
}
}
编译后:
D:\Program\demo\bin>java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -Xcomp -XX:CompileCommand=dontinline,*.Bar.sum -XX:CompileCommand=compileonly,*Bar.sum demo.Bar
Java HotSpot(TM) 64-Bit Server VM warning: PrintAssembly is enabled; turning on DebugNonSafepoints to gain additional output
CompilerOracle: unrecognized line
"dontinline * Bar sum"
Unrecognized text after command: sum
CompilerOracle: compileonly *Bar.sum
Loaded disassembler from D:\jdk1.7\jre\bin\server\hsdis-amd64.dll
Decoding compiled method 0x00000000032431d0:
Code:
[Disassembling for mach='i386:x86-64']
[Entry Point]
[Constants]
# {method} 'sum' '(I)I' in 'demo/Bar'
# this: rdx:rdx = 'demo/Bar'
# parm0: r8 = int
# [sp+0x20] (sp of caller)
0x0000000003243300: mov 0x8(%rdx),%r10d
0x0000000003243304: shl $0x3,%r10
0x0000000003243308: cmp %r10,%rax
0x000000000324330b: jne 0x0000000003217a60 ; {runtime_call}
0x0000000003243311: data16 xchg %ax,%ax
0x0000000003243314: nopl 0x0(%rax,%rax,1)
0x000000000324331c: data16 data16 xchg %ax,%ax
[Verified Entry Point]
0x0000000003243320: sub $0x18,%rsp
0x0000000003243327: mov %rbp,0x10(%rsp) ;*synchronization entry
; - demo.Bar::sum@-1 (line 9)
0x000000000324332c: movabs $0x7d5d9b0a8,%r10 ; {oop(a 'java/lang/Class' = 'demo/Bar')}
0x0000000003243336: mov 0x58(%r10),%r10d
0x000000000324333a: add 0xc(%rdx),%r10d
0x000000000324333e: mov %r8d,%eax
0x0000000003243341: add %r10d,%eax ;*iadd
; - demo.Bar::sum@9 (line 9)
0x0000000003243344: add $0x10,%rsp
0x0000000003243348: pop %rbp
0x0000000003243349: test %eax,-0x230334f(%rip) # 0x0000000000f40000
; {poll_return}
0x000000000324334f: retq
0x0000000003243350: hlt
0x0000000003243351: hlt
0x0000000003243352: hlt
0x0000000003243353: hlt
0x0000000003243354: hlt
0x0000000003243355: hlt
0x0000000003243356: hlt
0x0000000003243357: hlt
0x0000000003243358: hlt
0x0000000003243359: hlt
0x000000000324335a: hlt
0x000000000324335b: hlt
0x000000000324335c: hlt
0x000000000324335d: hlt
0x000000000324335e: hlt
0x000000000324335f: hlt
[Exception Handler]
[Stub Code]
0x0000000003243360: jmpq 0x00000000032400a0 ; {no_reloc}
[Deopt Handler Code]
0x0000000003243365: callq 0x000000000324336a
0x000000000324336a: subq $0x5,(%rsp)
0x000000000324336f: jmpq 0x0000000003219000 ; {runtime_call}
0x0000000003243374: hlt
0x0000000003243375: hlt
0x0000000003243376: hlt
0x0000000003243377: hlt
JDK的可视化工具
1.Java监视与管理控制台:JConsole
启动JConsole:JDK/bin/jconsole.exe
功能:内存监控、线程监控
2.多合一故障处理工具:VisualVM
Visual插件安装
功能:生成、浏览堆转储快照
分析程序性能
BTrace动态日志跟踪
官方插件下载地址:VisualVM: Plugins Centers