《Java 虛擬機(jī)原理》6.1 實(shí)戰(zhàn) —— JDK監(jiān)控及可視化工具

一、JDK命令行工具

1.查看所有Java進(jìn)程 - jps

jps(JVM Process Status) 命令類似 UNIX 的?ps?命令。

jps -q?:只輸出進(jìn)程的本地虛擬機(jī)唯一 ID。

C:\Users\SnailClimb>jps

7360 NettyClient2

jps -l:輸出主類的全名,如果進(jìn)程執(zhí)行的是 Jar 包,輸出 Jar 路徑

C:\Users\SnailClimb>jps -l

7360 firstNettyDemo.NettyClient2

17396

7972 org.jetbrains.jps.cmdline.Launcher

jps -v:輸出虛擬機(jī)進(jìn)程啟動(dòng)時(shí) JVM 參數(shù)。

jps -m:輸出傳遞給 Java 進(jìn)程 main() 函數(shù)的參數(shù)。

2.監(jiān)視虛擬機(jī)各種運(yùn)行狀態(tài)信息??- jstat

jstat(JVM Statistics Monitoring Tool) 使用于監(jiān)視虛擬機(jī)各種運(yùn)行狀態(tài)信息的命令行工具。 它可以顯示本地或者遠(yuǎn)程(需要遠(yuǎn)程主機(jī)提供 RMI 支持)虛擬機(jī)進(jìn)程中的類信息、內(nèi)存、垃圾收集、JIT 編譯等運(yùn)行數(shù)據(jù),在沒有 GUI,只提供了純文本控制臺(tái)環(huán)境的服務(wù)器上,它將是運(yùn)行期間定位虛擬機(jī)性能問題的首選工具。

jstat?命令使用格式:

jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

比如?jstat -gc -h3 31736 1000 10表示分析進(jìn)程 id 為 31736 的 gc 情況,每隔 1000ms 打印一次記錄,打印 10 次停止,每 3 行后打印指標(biāo)頭部。

常見的 option 如下:

jstat -class vmid?:顯示 ClassLoader 的相關(guān)信息;

jstat -compiler vmid?:顯示 JIT 編譯的相關(guān)信息;

jstat -gc vmid?:顯示與 GC 相關(guān)的堆信息;

jstat -gccapacity vmid?:顯示各個(gè)代的容量及使用情況;

jstat -gcnew vmid?:顯示新生代信息;

jstat -gcnewcapcacity vmid?:顯示新生代大小與使用情況;

jstat -gcold vmid?:顯示老年代和永久代的信息;

jstat -gcoldcapacity vmid?:顯示老年代的大??;

jstat -gcpermcapacity vmid?:顯示永久代大小;

jstat -gcutil vmid?:顯示垃圾收集信息;

3.實(shí)時(shí)地查看和調(diào)整虛擬機(jī)各項(xiàng)參數(shù) - jinfo

jinfo vmid :輸出當(dāng)前 jvm 進(jìn)程的全部參數(shù)和系統(tǒng)屬性 。

jinfo -flag name vmid :輸出對(duì)應(yīng)名稱的參數(shù)的具體值。比如輸出 MaxHeapSize、查看當(dāng)前 jvm 進(jìn)程是否開啟打印 GC 日志 ( -XX:PrintGCDetails :詳細(xì) GC 日志模式,這兩個(gè)都是默認(rèn)關(guān)閉的)。

C:\Users\SnailClimb>jinfo -flag MaxHeapSize 17340

-XX:MaxHeapSize=2124414976

C:\Users\SnailClimb>jinfo -flag PrintGC 17340

-XX:-PrintGC

使用 jinfo 可以在不重啟虛擬機(jī)的情況下,可以動(dòng)態(tài)的修改 jvm 的參數(shù)。尤其在線上的環(huán)境特別有用,請(qǐng)看下面的例子:

jinfo -flag [+|-]name vmid?開啟或者關(guān)閉對(duì)應(yīng)名稱的參數(shù)。

C:\Users\SnailClimb>jinfo -flag PrintGC 17340

-XX:-PrintGC

C:\Users\SnailClimb>jinfo -flag +PrintGC 17340

C:\Users\SnailClimb>jinfo -flag PrintGC 17340

-XX:+PrintGC

4.生成堆轉(zhuǎn)儲(chǔ)快照 - jmap

jmap(Memory Map for Java)命令用于生成堆轉(zhuǎn)儲(chǔ)快照。 如果不使用?jmap?命令,要想獲取 Java 堆轉(zhuǎn)儲(chǔ),可以使用?“-XX:+HeapDumpOnOutOfMemoryError”?參數(shù),可以讓虛擬機(jī)在 OOM 異常出現(xiàn)之后自動(dòng)生成 dump 文件,Linux 命令下可以通過?kill -3?發(fā)送進(jìn)程退出信號(hào)也能拿到 dump 文件。

jmap?的作用并不僅僅是為了獲取 dump 文件,它還可以查詢 finalizer 執(zhí)行隊(duì)列、Java 堆和永久代的詳細(xì)信息,如空間使用率、當(dāng)前使用的是哪種收集器等。和jinfo一樣,jmap有不少功能在 Windows 平臺(tái)下也是受限制的。

示例:將指定應(yīng)用程序的堆快照輸出到桌面。后面,可以通過 jhat、Visual VM 等工具分析該堆文件。

C:\Users\SnailClimb>jmap -dump:format=b,file=C:\Users\SnailClimb\Desktop\heap.hprof 17340

Dumping heap to C:\Users\SnailClimb\Desktop\heap.hprof ...

Heap dump file created

5.生成虛擬機(jī)當(dāng)前時(shí)刻的線程快照 - jstack

jstack(Stack Trace for Java)命令用于生成虛擬機(jī)當(dāng)前時(shí)刻的線程快照。線程快照就是當(dāng)前虛擬機(jī)內(nèi)每一條線程正在執(zhí)行的方法堆棧的集合。

生成線程快照的目的主要是定位線程長(zhǎng)時(shí)間出現(xiàn)停頓的原因,如線程間死鎖、死循環(huán)、請(qǐng)求外部資源導(dǎo)致的長(zhǎng)時(shí)間等待等都是導(dǎo)致線程長(zhǎng)時(shí)間停頓的原因。線程出現(xiàn)停頓的時(shí)候通過jstack來查看各個(gè)線程的調(diào)用堆棧,就可以知道沒有響應(yīng)的線程到底在后臺(tái)做些什么事情,或者在等待些什么資源。

public class DeadLockDemo {

private static Objectresource1 =new Object();//資源1

? ? private static Objectresource2 =new Object();//資源2

? ? public static void main(String[] args) {

new Thread(() -> {

synchronized (resource1) {

System.out.println(Thread.currentThread() +"get resource1");

? ? ? ? ? ? ? ? try {

Thread.sleep(1000);

? ? ? ? ? ? ? ? }catch (InterruptedException e) {

e.printStackTrace();

? ? ? ? ? ? ? ? }

System.out.println(Thread.currentThread() +"waiting get resource2");

? ? ? ? ? ? ? ? synchronized (resource2) {

System.out.println(Thread.currentThread() +"get resource2");

? ? ? ? ? ? ? ? }

}

}, "線程 1").start();

? ? ? ? new Thread(() -> {

synchronized (resource2) {

System.out.println(Thread.currentThread() +"get resource2");

? ? ? ? ? ? ? ? try {

Thread.sleep(1000);

? ? ? ? ? ? ? ? }catch (InterruptedException e) {

e.printStackTrace();

? ? ? ? ? ? ? ? }

System.out.println(Thread.currentThread() +"waiting get resource1");

? ? ? ? ? ? ? ? synchronized (resource1) {

System.out.println(Thread.currentThread() +"get resource1");

? ? ? ? ? ? ? ? }

}

}, "線程 2").start();

? ? }

}


結(jié)果:

Thread[線程 1,5,main]get resource1

Thread[線程 2,5,main]waiting get resource1

Thread[線程 1,5,main]waiting get resource2

線程 A 通過 synchronized (resource1) 獲得 resource1 的監(jiān)視器鎖,然后通過Thread.sleep(1000);讓線程 A 休眠 1s 為的是讓線程 B 得到執(zhí)行然后獲取到 resource2 的監(jiān)視器鎖。線程 A 和線程 B 休眠結(jié)束了都開始企圖請(qǐng)求獲取對(duì)方的資源,然后這兩個(gè)線程就會(huì)陷入互相等待的狀態(tài),這也就產(chǎn)生了死鎖。

進(jìn)入jdk/bin目錄,例如,C:\Program Files\Java\jdk1.8.0_101\bin

通過?jstack?命令分析:死鎖

死鎖

二、JDK可視化分析工具

1.JConsole:Java 監(jiān)視與管理控制臺(tái)

JConsole 是基于 JMX 的可視化監(jiān)視、管理工具。可以很方便的監(jiān)視本地及遠(yuǎn)程服務(wù)器的 java 進(jìn)程的內(nèi)存使用情況。你可以在控制臺(tái)輸出console命令啟動(dòng)或者在 JDK 目錄下的 bin 目錄找到j(luò)console.exe然后雙擊啟動(dòng)。

連接 Jconsole

console

如果需要使用 JConsole 連接遠(yuǎn)程進(jìn)程,可以在遠(yuǎn)程 Java 程序啟動(dòng)時(shí)加上下面這些參數(shù):

-Djava.rmi.server.hostname=外網(wǎng)訪問 ip 地址 -Dcom.sun.management.jmxremote.port=60001 //監(jiān)控的端口號(hào)-Dcom.sun.management.jmxremote.authenticate=false //關(guān)閉認(rèn)證-Dcom.sun.management.jmxremote.ssl=false

在使用 JConsole 連接時(shí),遠(yuǎn)程進(jìn)程地址如下:

外網(wǎng)訪問 ip 地址:60001

查看 Java 程序概況

java程序概況

內(nèi)存監(jiān)控

JConsole 可以顯示當(dāng)前內(nèi)存的詳細(xì)信息。不僅包括堆內(nèi)存/非堆內(nèi)存的整體信息,還可以細(xì)化到 eden 區(qū)、survivor 區(qū)等的使用情況,如下圖所示。

點(diǎn)擊右邊的“執(zhí)行 GC(G)”按鈕可以強(qiáng)制應(yīng)用程序執(zhí)行一個(gè) Full GC。

新生代 GC(Minor GC):指發(fā)生新生代的的垃圾收集動(dòng)作,Minor GC 非常頻繁,回收速度一般也比較快。

老年代 GC(Major GC/Full GC):指發(fā)生在老年代的 GC,出現(xiàn)了 Major GC 經(jīng)常會(huì)伴隨至少一次的 Minor GC(并非絕對(duì)),Major GC 的速度一般會(huì)比 Minor GC 的慢 10 倍以上。

內(nèi)存監(jiān)控

線程監(jiān)控

類似jstack命令,不過這個(gè)是可視化的。

最下面有一個(gè)"檢測(cè)死鎖 (D)"按鈕,點(diǎn)擊這個(gè)按鈕可以自動(dòng)為你找到發(fā)生死鎖的線程以及它們的詳細(xì)信息 。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容