在jdk中提供了一些工具帮助开发人员解决一些问题。上一篇中提到的jps,jstack就是出自jdk。
jdk/bin目录下提供了很多exe文件其实都是jar文件的包装,真正的实现在jdk/lib/tools.jar中
jps命令可以查看所有的Java进程
jps存放在JAVA_HOME/bin/jps,使用时为了方便请将JAVA_HOME/bin/加入到Path。
[no1@localhost ~]$ jps
9415 2.jar
9672 Jps
可以查看Java虚拟机运行时信息,可以查看堆信息情况,GC情况
jstat -
查看pid为9415的ClassLoad相关信息
[no1@localhost ~]$ jstat -class 9415
Loaded Bytes Unloaded Bytes Time
427 880.6 0 0.0 0.08
[no1@localhost ~]$ jstat -compiler 9415
Compiled Failed Invalid Time FailedType FailedMethod
121 0 0 0.17 0
jinfo可以用来查看正在运行的Java应用程序的扩展参数,甚至支持运行时修改部分参数。
jinfo <option> pid
pid 即 Java进程ID
options参数可以是如下信息
例如查看是否打印GC信息,这里是输出结果 -XX:-PrintGC -表示不打印
[no1@localhost ~]$ jinfo -flag PrintGC 9415
-XX:-PrintGC
修改参数,开启打印GC
开启打印GC信息
[no1@localhost ~]$ jinfo -flag +PrintGC 10056
再来查看是否打印GC信息,发现已经开启
[no1@localhost ~]$ jinfo -flag PrintGC 10056
-XX:+PrintGC
jmap命令可以生成Java程序的堆dump文件,也可以查看堆对象实例的统计信息,查看ClassLoader的信息以及finalizer队列。
使用方式:jmap [ option ] pid
jmap -histo 10056 > c:/1.txt
输出:
[no1@localhost ~]$ jmap -dump:format=b,file=/home/no1/dump.hprof 10056
Dumping heap to /home/no1/dump.hprof ...
Heap dump file created
dump出的文件可以用 jhat(不推荐使用,功能有限),visual vm,MAT,IBM heapAnalyzer,Eclipse Memory Analyzer等打开查看
不推荐使用,功能有限,并且一般情况下导出服务器上的机器堆信息都不会在服务器上进行分析消耗资源,而是拿到其他机器进行分析。
visual vm,MAT,IBM heapAnalyzer,Eclipse Memory Analyzer等这些都可以代替它。
jstack(stack Trace for Java) 命令用于生成虚拟机当前时刻的线程快照。线程快照即:当前虚拟机内每一个线程正在执行的方法的堆栈集合。可以通过这个快照看到每一个线程都执行在哪个方法上了,状态是什么样子的(运行,等待等)。
jstack -l pid
[no1@localhost ~]$ jstack -l 10056
2017-11-13 16:34:55
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.151-b12 mixed mode):
"Attach Listener" #12 daemon prio=9 os_prio=0 tid=0x00007f2414001000 nid=0x277b waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"DestroyJavaVM" #11 prio=5 os_prio=0 tid=0x00007f2450008800 nid=0x2749 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"Thread-2" #10 prio=5 os_prio=0 tid=0x00007f2450175000 nid=0x2756 waiting on condition [0x00007f243d8dd000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at HoldIOMain$T2.run(HoldIOMain.java:34)
at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
- None
"Thread-1" #9 prio=5 os_prio=0 tid=0x00007f2450173800 nid=0x2755 waiting on condition [0x00007f243d9de000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at HoldIOMain$T2.run(HoldIOMain.java:34)
at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
- None
"Thread-0" #8 prio=5 os_prio=0 tid=0x00007f2450171800 nid=0x2754 runnable [0x00007f243dadf000]
java.lang.Thread.State: RUNNABLE
at java.io.FileOutputStream.write(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:290)
at HoldIOMain$T1.run(HoldIOMain.java:12)
at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
- None
在JDK 1.7之后,新增了一个命令行工具jcmd。它是一个多功能工具,可以用来导出堆,查看java进程,导出线程信息,执行GC等。
jcmd具有jmap命令大部分功能,oracle官方网站推荐jcmd替代jmap。
[no1@localhost ~]$ jcmd -l
10056 /home/no1/soft/2.jar
10252 sun.tools.jcmd.JCmd -l
参数说明:jcmd -l 可以查看所有的Java虚拟机,类似jps
-l命令是列出所有Java虚拟机,针对每一个虚拟机可以通过help命令查询所支持的命令。
语法 jcmd pid help
[no1@localhost ~]$ jcmd 10056 help
10056:
The following commands are available:
JFR.stop
JFR.start
JFR.dump
JFR.check
VM.native_memory
VM.check_commercial_features
VM.unlock_commercial_features
ManagementAgent.stop
ManagementAgent.start_local
ManagementAgent.start
GC.rotate_log
Thread.print
GC.class_stats
GC.class_histogram
GC.heap_dump
GC.run_finalization
GC.run
VM.uptime
VM.flags
VM.system_properties
VM.command_line
VM.version
help
[no1@localhost ~]$ jcmd 10056 VM.uptime
10056:
4140.026 s
[no1@localhost ~]$ jcmd 10056 GC.heap_dump /home/no1/gcdump.dump
10056:
Heap dump file created
Jconsole是jdk自带的图形化工具,在%JAVA_HOME%/bin 目录下jconsole.exe打开即可启动。
可以连接本地和远程连接两种方式。
编辑tomcat下 catalina.bat 文件 在 set JAVA_OPTS 加上参数即可
配置信息如下:设置ip,端口,不需要认证(不需要账号密码),不开启ssl
-Djava.rmi.server.hostname=127.0.0.1
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=6789
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
需要账号密码:设置ip,端口,需要账号密码认证,不开启ssl,
找到jdk目录结果下的jmxremote.password.template文件,将其重命名为jmxremote.password,这个文件里面设置用户的密码,并且要把这个文件权限改成当前用户读写,在linux中就是600
里面还有一个jmxremote.access文件是用来控制用户操作权限的,jmxremote.password控制用户的密码
-Djava.rmi.server.hostname=127.0.0.1
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=6789
-Dcom.sun.management.jmxremote.authenticate=true
-Dcom.sun.management.jmxremote.pwd.file=D:/jdk1.7.0_40/jre/lib/management/jmxremote.password
-Dcom.sun.management.jmxremote.ssl=false
VisualVM是一个多功能合一的故障诊断,性能监控的可视化工具。集成了多种性能统计工具的功能,在jdk update7版本以后跟随jdk一起发布,也可以去官网独立下载http://visualvm.java.net/。
VisualVm可以做到:
在%JAVA_HOME%/bin目录下jvisualvm.exe 双击即可打开。
左侧本地会列出机器上的所有Java程序:图中有tomcat,eclipse,visual vm。
远程 可以连接到远程机器的Java虚拟机进行检测。需要通过jstatd。
快照可以浏览导出的本地文件进行分析。
工具–》插件
这里 如果检查更新之后无法使用。可能就是配置的更新地址有问题,需要更改一下,如下图进行编辑。
这个地址对照 插件的地址 https://visualvm.github.io/pluginscenters.html
Btrace可以在不停机的情况下,通过字节码的注入动态监控系统运行的情况,可以跟踪指定的方法调用,构造函数调用和系统内存等信息。
如图选择 Btrace workbench进行安装。
安装完成之后选择左边的Java程序右键点击trace application就可以打开Btrace了
如图这里选择tomcat右键操作
Java代码:接收控制台输入的两个数字,输出两个数字求和的结果
package com.jx;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class BtraceTest{
public int add(int a,int b){
return a+b;
}
public static void main(String[] args) {
try {
BtraceTest test = new BtraceTest();
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
int a = 0 ,b = 0;
for(int i = 0 ; i < 2 ; i++){
String line = reader.readLine();
if(i == 0 ){
a = Integer.parseInt(line);
}else{
b = Integer.parseInt(line);
}
}
reader.close();
System.out.println(test.add(a, b));
} catch (IOException e) {
e.printStackTrace();
}
}
}
import com.sun.btrace.BTraceUtils;
import static com.sun.btrace.BTraceUtils.*;
import com.sun.btrace.annotations.*;
@BTrace
public class Btrace {
@OnMethod(
clazz="com.jx.BtraceTest",
method="add",
location=@Location(Kind.RETURN)
)
public static void functest(@Self com.jx.BtraceTest instance,int a,int b,@Return int result){
println("调用堆栈");
jstack();
println(strcat("方法参数A:",str(a)));
println(strcat("方法参数B:",str(b)));
println(strcat("返回结果:",str(result)));
}
}
先运行Java代码,等待输入数字。
这个时候可以visualvm监控到Java程序已经运行,右键选择Java程序 trace application 输入 trace 代码,点击start就可以开始监控。
回到Java程序输入数字 回过头来可以看到 trace 监听到了参数和返回值。
* Starting BTrace task
** Compiling the BTrace script ...
*** Compiled
** Instrumenting 1 classes ...
*** Done
** BTrace up&running
*** Done
** BTrace up&running
调用堆栈
com.jx.BtraceTest.add(BtraceTest.java:11)
com.jx.BtraceTest.main(BtraceTest.java:28)
方法参数A5
方法参数B3
返回结果8
** BTrace has stopped
** BTrace has stopped