JDK命令
以下介紹的JDK命令主要是處理應用程序性能問題、定位程序故障等情況。
JDK監(jiān)控和故障處理工具
| 名稱 | 主要作用 |
|---|---|
| jps | 顯示指定系統(tǒng)內(nèi)所有的HotSpot虛擬機進程 |
| jstat | 收集HotSpot虛擬機各方面的運行數(shù)據(jù) |
| jinfo | 顯示虛擬機配置信息 |
| jmap | 生成虛擬機的內(nèi)存轉儲快照(heapdump文件) |
| jhat | 分析heapdump文件,會建立一個HTTP/HTML服務器,讓用戶可以在瀏覽器查看分析結果 |
| jstack | 顯示細膩的線程快照 |
jps:虛擬機進程狀況工具
JVM Process Status Tool,顯示指定系統(tǒng)內(nèi)所有的虛擬機進程。列出正在運行的細膩及進程,并顯示虛擬機執(zhí)行主類以及這些進程的本地虛擬機唯一ID。類似ps。
-q:只輸出進程 ID
-m:輸出傳入 main 方法的參數(shù)
-l:輸出完全的包名,應用主類名,jar的完全路徑名
-v:輸出jvm參數(shù)
-V:輸出通過flag文件傳遞到JVM中的參數(shù)

與ps區(qū)別:啟動多個虛擬機進程時,無法根據(jù)進程名稱定位時,只能依賴jps命令顯示主類的功能區(qū)分。
jstat:虛擬機統(tǒng)計信息監(jiān)視工具
JVM Statistics Monitoring Tool,用于收集虛擬機各方面的運行數(shù)據(jù)??梢燥@示本地或者遠程虛擬機進程中的類裝載、內(nèi)存、垃圾收集、JIT編譯等運行數(shù)據(jù)。
-class 顯示ClassLoad的相關信息;
-compiler 顯示JIT編譯的相關信息;
-gc 顯示和gc相關的堆信息;
-gccapacity 顯示各個代的容量以及使用情況;
-gcmetacapacity 顯示metaspace的大小
-gcnew 顯示新生代信息;
-gcnewcapacity 顯示新生代大小和使用情況;
-gcold 顯示老年代和永久代的信息;
-gcoldcapacity 顯示老年代的大小;
-gcutil 顯示垃圾收集信息;
-gccause 顯示垃圾回收的相關信息(通-gcutil),同時顯示最后一次或當前正在發(fā)生的垃圾回收的誘因;
-printcompilation 輸出JIT編譯的方法信息;

解析:jstat -gc 13504 2000 20(每隔2秒監(jiān)控一次,共做10次)
| 名稱 | 主要作用 |
|---|---|
| S0C,S1C | survivor space 幸存區(qū)0,1當前空間大小 |
| S0U,S1U | survivor space 幸存區(qū)0,1使用空間大小 |
| EC | Eden space 伊甸園當前空間大小 |
| EU | Eden space 伊甸園使用空間大小 |
| OC | Old space老年代當前空間大小 |
| OU | Old space老年代使用空間大小 |
| MC | Metaspace 元空間總空間大小 |
| MU | Metaspace 元空間使用空間大小 |
| CCSC | 壓縮類空間大小 |
| CCSU | 壓縮類空間使用大小 |
| YGC | YoungGC年輕代垃圾回收次數(shù) |
| YGCT | YoungGC年輕代垃圾回收時間 |
| FGC | FullGC老年代垃圾回收次數(shù) |
| FGCT | FullGC老年代垃圾回收時間 |
| GCT | 全部GC時間 |
jstat參數(shù)解析參考:https://blog.csdn.net/maosijunzi/article/details/46049117
jinfo:java配置信息工具
Configuration Info for Java,顯示虛擬機配置信息??梢詫崟r查看虛擬機的相關配置信息。
no option 輸出全部的參數(shù)和系統(tǒng)屬性
-flag name 輸出對應名稱的參數(shù)
-flag [+|-]name 開啟或者關閉對應名稱的參數(shù)
-flag name=value 設定對應名稱的參數(shù)
-flags 輸出全部的參數(shù)
-sysprops 輸出系統(tǒng)屬性
eg:jinfo -flags pid 描述:輸出全部的參數(shù)
jmap:java內(nèi)存映射工具
Memory Map for Java,生成虛擬機的內(nèi)存轉儲快照(heapdump或dump文件)。還可以查詢finalize執(zhí)行隊列,java堆和永久帶的詳細信息,如空間使用率,當前使用的哪種收集器等等。
-heap: 顯示Java堆詳細信息
-histo[:live]: 顯示堆中對象的統(tǒng)計信息
-finalizerinfo: 顯示在F-Queue隊列等待Finalizer線程執(zhí)行finalizer方法的對象
-dump:<dump-options>:生成堆轉儲快照
-F:當-dump沒有響應時,使用-dump或者-histo參數(shù). 在這個模式下,live子參數(shù)無效.
eg1: jmap -heap 16840堆信息

eg2: jmap -dump:format=b,file=aa.bin 57524

jhat:虛擬機堆轉儲快照分析工具
JVM Heap Dump Browser,用于分析heapdump文件,建立一個Http/HTML服務器,查看分析結果。與jmap搭配使用,分析jmap生成的快照。
eg: jhat aa.bin

訪問:http://localhost:7000/ 即可看到當時的快照信息,默認以包為單位顯示,不常使用不做具體分析。

jstack:java堆棧跟蹤工具
Stack Trace for Java,jstack是jdk自帶的線程堆棧分析工具,使用該命令可以查看或導出 Java 應用程序中線程堆棧信息。用于生成虛擬機當前時刻的線程快照(一般稱為threaddump或者javacore文件)。線程快照就是當前虛擬機每一條線程正在執(zhí)行的方法堆棧的集合,生成的線程快照的主要目的是定位線程出現(xiàn)長時間停頓的原因,如線程間死鎖,死循環(huán),請求外部資源導致的長時間等待等等。
-l 長列表. 打印關于鎖的附加信息,例如屬于java.util.concurrent 的 ownable synchronizers列表.
-F 當’jstack [-l] pid’沒有相應的時候強制打印棧信息
-m 打印java和native c/c++框架的所有棧信息.
-h | -help 打印幫助信息
jstack -F pid >> a.log

可以用其來檢查死鎖。線程1與線程2都只進行加鎖操作,不進行釋放鎖。此時發(fā)生死鎖現(xiàn)象。
ReentrantLock lock1 = new ReentrantLock();
ReentrantLock lock2 = new ReentrantLock();
Thread t1 = new Thread(() -> {
lock1.lock();
try {
TimeUnit.SECONDS.sleep(1);
} catch (Exception e) {}
lock2.lock();
});
Thread t2 = new Thread(() -> {
lock1.lock();
try {
TimeUnit.SECONDS.sleep(1);
} catch (Exception e) {}
lock2.lock();
});
t1.start();
t2.start();

JDK可視化工具
若當真排查問題使用命令行,那選擇放棄可以不?不過,好在JDK提供了兩個功能強大的可視化工具(JConsole,JVisualVM),其中JVisualVM現(xiàn)已成為Oracle主力推動的多合一故障處理工具,兼容JConsole。
jconsole
Jconsole (Java Monitoring and Management Console),一種基于JMX的可視化監(jiān)視、管理工具。包括以下基本功能:概述、內(nèi)存、線程、類、VM概要、MBean... ...

jvisualVM
VisualVM 已在JDK6.0 update 7 中自帶(java啟動時不需要特定參數(shù),監(jiān)控工具在bin/jvisualvm.exe),能夠監(jiān)控線程,內(nèi)存情況,查看方法的CPU時間和內(nèi)存中的對 象,已被GC的對象,反向查看分配的堆棧(如100個String對象分別由哪幾個對象分配出來的)。
使用jvisualVM要做到什么:出現(xiàn)OOM或者內(nèi)存泄漏后,可以使用它定位到具體的代碼。
使用介紹:安裝插件

簡單介紹
1.基本信息

2.heapdump 對應命令jmap

2.threaddump對應命令jstack

問題思考:
線上如何監(jiān)控內(nèi)存,cpu情況?
線上如何定位OOM問題,如果是偶發(fā),無規(guī)律,即不能通過jvisualVM監(jiān)控。
生產(chǎn)實戰(zhàn)演示
見我的另一篇文章生產(chǎn)內(nèi)存溢出問題
BTrace:動態(tài)日志跟蹤
BTrace是一個安全的JVM動態(tài)追蹤工具,典型的使用場景是,“我要查個問題,可那個方法沒有打印入口參數(shù)和返回結果日志”,“我想看某個方法的執(zhí)行耗時”,“我想查看某方法如System.GC()的調(diào)用棧”等等,這些都是BTrace可以小試牛刀的地方。它的優(yōu)勢是,直接attach應用JVM,不用重啟應用進程,可比較快速方便地定位問題。
/* BTrace Script Template */
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;
import com.sun.btrace.BTraceUtils;
@BTrace(unsafe = true)// 表示這是一個BTrace跟蹤腳本,并啟用unsafe模式(因為使用了BTraceUtils以外的方法,即String.valueOf(obj))
public class TracingScript {
@OnMethod(clazz="com.example.demo.web.UserController", //類的全名
method="login",// 方法名
location=@Location(Kind.RETURN))// 表示跟蹤某個類的某個方法,位置為方法返回處
public static void test(@Self com.example.demo.web.UserController self,
com.example.demo.constant.UserVo userVo,@Return String result) {
println("test start!");
jstack();
println(self);
println(String.valueOf(userVo)) ;
println(result);
println("test end!");
}
}
結果:
