JVM筆記8-虛擬機(jī)性能監(jiān)控與故障處理工具
時(shí)間:2023-06-28 00:57:01 | 來(lái)源:網(wǎng)站運(yùn)營(yíng)
時(shí)間:2023-06-28 00:57:01 來(lái)源:網(wǎng)站運(yùn)營(yíng)
JVM筆記8-虛擬機(jī)性能監(jiān)控與故障處理工具:
1.JDK命令行工具 Java開(kāi)發(fā)人員肯定都知道JDK的bin目錄有“java.exe”,"javac.exe"這兩個(gè)命令行工具,但并非所有程序員都了解過(guò)JDK的bin目錄之中其他命令行程序的作用。每次JDK更新,bin目錄下命令行工具的數(shù)量和功能總會(huì)不知不覺(jué)地增強(qiáng)。
主要包括用于監(jiān)控虛擬機(jī)和故障處理的工具。這些工具被Sun公司作為禮物附贈(zèng)給JDK的使用者。如下圖:
可以看到這些工具的程序體積都異常小巧?;径挤€(wěn)定在17K左右。這并非JDK開(kāi)發(fā)團(tuán)隊(duì)刻意把他們制作得如此精煉,而是這些命令行工具大多數(shù)是JDK/lib/tools.jar類庫(kù)的一層薄包裝而已,它們主要的功能代碼是在tools類庫(kù)中實(shí)現(xiàn)的。
之所以這樣做,是因?yàn)楫?dāng)應(yīng)用程序部署到生產(chǎn)環(huán)境后,無(wú)論是直接接觸物理服務(wù)器還是遠(yuǎn)程Telnet到服務(wù)器上都可能會(huì)受到限制。借助tools.jar類庫(kù)里面的接口,我們可以直接在應(yīng)用程序中實(shí)現(xiàn)功能強(qiáng)大的監(jiān)控分析功能。
下面列舉JDK主要命令行監(jiān)控工具的用途。
1.jps:虛擬機(jī)就進(jìn)程狀況工具 JDK的很多小工具的名字都參考了UNIX命令的命名方式,jps名字像UNIX的ps命令之外,也和ps命令類似:可以列出正在運(yùn)行的虛擬機(jī)進(jìn)程。并顯示虛擬機(jī)執(zhí)行主類(Main Class,main()函數(shù)所在的類)名稱以及這些進(jìn)程的本地虛擬機(jī)唯一ID(Local Virtual Machine Identifier,LVMID)。
雖然功能比較單一,但它是使用頻率最高的JDK命令行工具,因?yàn)槠渌腏DK工具大多需要輸入它查詢到的LVMID來(lái)確定要監(jiān)控的是哪一個(gè)虛擬機(jī)進(jìn)程。對(duì)于本地虛擬機(jī)進(jìn)程來(lái)說(shuō),LVMID與操作系統(tǒng)的進(jìn)程ID是一致的。使用Windows的任務(wù)管理器或者UNIX的ps命令也可以
查詢到虛擬機(jī)進(jìn)程的LVMID,但如果同時(shí)啟動(dòng)多個(gè)虛擬機(jī)進(jìn)程,無(wú)法根據(jù)進(jìn)程名稱定位時(shí),那只有依賴jps命令顯示主類的功能才能區(qū)分了。
jps命令格式如下:
現(xiàn)在我們打開(kāi)一個(gè)eclispe,寫一段程序,例子如下:
package hjc.test9a;
import java.util.Scanner;
/**
* Created by cong on 2018/4/5.
*/
public class Main {
public Main() {
}
public static void main(String[] args) {
Scanner sc = new Scanner(
http://System.in);
sc.next();
}
}
連續(xù)運(yùn)行2次,打開(kāi)cmd,再用jps查看,如下:
2.jstat:虛擬機(jī)統(tǒng)計(jì)信息監(jiān)控工具 jstat(JVM Statistics Monitoring Tool)是用于監(jiān)控虛擬機(jī)各種運(yùn)行狀態(tài)信息的命令行工具。它可以顯示本地或者遠(yuǎn)程虛擬機(jī)進(jìn)程中的類裝載,內(nèi)存,垃圾收集,JIT編譯等運(yùn)行數(shù)據(jù),在沒(méi)有GUI圖形界面,只提供了純文本控制臺(tái)環(huán)境的服務(wù)器上,
它將是運(yùn)行期定位虛擬機(jī)性能問(wèn)題的首選工具。
jstat命令格式為:
jstat [ option vmid [interval [s|ms] [count]] ]
對(duì)于命令格式中的VMID與LVMID需要特別說(shuō)明一下:如果是本地虛擬機(jī)進(jìn)程,VMID與LVMID是一致的,如果是遠(yuǎn)程虛擬機(jī)進(jìn)程,那VMID的格式應(yīng)當(dāng)是:
參數(shù)interval 和count代表查詢間隔和次數(shù),如果省略這兩個(gè)參數(shù),說(shuō)明只查詢一次。假設(shè)要美250毫秒查詢一次進(jìn)程2764垃圾收集情況,一個(gè)查詢20次,那命令應(yīng)當(dāng)是:
jstat -gc 2764 250 20
選項(xiàng)option代表著用戶希望查詢的虛擬機(jī)信息,主要分為3類:類裝載,垃圾收集,運(yùn)行期編譯狀況,具體選項(xiàng)及作用請(qǐng)參考如下列表:
jstat 監(jiān)控選項(xiàng)眾多,這里僅舉一個(gè)例子演示如何查看監(jiān)控結(jié)果。繼續(xù)運(yùn)行上面的例子如下:
3.jinfo:Java配置信息工具 jinfo(Configuration Info for Java) 的作用是實(shí)時(shí)地查看和調(diào)整虛擬機(jī)各項(xiàng)參數(shù)。使用jps命令的-v參數(shù)可以查看虛擬機(jī)啟動(dòng)時(shí)顯式指定的參數(shù)列表,但如果想知道未被顯式指定的參數(shù)的系統(tǒng)默認(rèn)值,除了去找資料,就只能使用jinfo的-flag選項(xiàng)進(jìn)行查詢了(如果
只限于JDK1.6或以上版本的話,使用java -XX:+PrintFlagsFianl查看參數(shù)默認(rèn)值也是一個(gè)很好的選擇),jinfo還可以使用-sysprops選項(xiàng)把虛擬機(jī)進(jìn)程的System.getProperties()的內(nèi)容打印出來(lái)。這個(gè)命令在JDK1.5時(shí)期已經(jīng)伴隨Linux的JDK發(fā)布,當(dāng)時(shí)只提供了信息查詢的功能,
JDK1.6之后,jinfo在Windows和Linux平臺(tái)都有提供,并且加入了運(yùn)行期修改參數(shù)的能力,可以使用-flag [+|-] name或者 -flag name=value 修改一部分運(yùn)行期可寫的虛擬機(jī)參數(shù)值。JDK1.6中,jinfo對(duì)于Windows平臺(tái)功能仍然有很大的限制,只提供了最基本的-flag選項(xiàng)。
jinfo的命令格式如下:
jinfo [option] pid
jmap:Java內(nèi)存映像工具 jmap命令用于生成堆轉(zhuǎn)儲(chǔ)快照(一般稱為heapdump 或者dump文件),如果不是用jmap命令,想要獲取Java堆轉(zhuǎn)儲(chǔ)快照,要有一些暴力手段,用-XX:HeapDumpOnOutOfMemoryError參數(shù),可以讓虛擬機(jī)在OOM異常出現(xiàn)之后自動(dòng)生成dump文件,通過(guò)-XX:HeapDumpOnCtrlBreak參數(shù)則
可以使用[Ctrl]+[Break]鍵讓虛擬機(jī)生成dump文件,又或者在Linux系統(tǒng)下通過(guò)Kill -3命令發(fā)送進(jìn)程退出信號(hào)嚇唬一下虛擬機(jī),也能拿到dump文件。jmap的作用并不僅僅是為了獲取dump文件,它還可以查詢finalize執(zhí)行隊(duì)列,java堆和永久代的詳細(xì)信息,如空間使用率,當(dāng)前用的是哪種收集器等。
jmap有不少功能在Windows平臺(tái)下都是受限制的,除了生成dump文件的-dump選項(xiàng)和用于查看每個(gè)類的實(shí)例,空間占用統(tǒng)計(jì)的-histo選項(xiàng)在所有操作系統(tǒng)都提供外,其余只能在Linux/Solaris下使用。
jmap命令格式:
jmap [option] vmid
option選項(xiàng)合法值與具體含義如下:
例子如下:
5.jhat:虛擬機(jī)堆轉(zhuǎn)儲(chǔ)快照分析工具 jhat命令與jmap搭配使用,來(lái)分析jmap生成的堆轉(zhuǎn)儲(chǔ)快照。jhat內(nèi)置了一個(gè)微型的HTTP/HTML服務(wù)器,生成dump文件的分析結(jié)果后,可以在瀏覽器查看。實(shí)際工作中,如果沒(méi)有別的工具可用,一般不會(huì)用jhat分析dump文件的。
原因有二:一是一般不會(huì)在部署應(yīng)用程序的服務(wù)器上直接分析dump文件,即使這樣做,也會(huì)盡量將dump文件復(fù)制到其他機(jī)器上進(jìn)行分析,因?yàn)榉治龉ぷ魇且粋€(gè)耗時(shí)并且消耗硬件資源的過(guò)程。另外一個(gè)原因是jhat的分析功能相對(duì)于簡(jiǎn)陋,
后面會(huì)提到專業(yè)的工具VisualVM,以及專業(yè)分析dump的Eclispe Memory Analyzer,等工具。
6.jstack:Java堆棧跟蹤工具 jstack命令用于生成虛擬機(jī)當(dāng)前時(shí)刻的線程快照(一般稱為threaddump或者javacore文件)。線程快照就是當(dāng)前虛擬機(jī)內(nèi)每一條線程正在執(zhí)行的方法堆棧集合,生成線程快照的主要目的是定位線程出現(xiàn)長(zhǎng)時(shí)間停頓的原因。線程出現(xiàn)停頓的時(shí)候通過(guò)
jstack來(lái)查看各個(gè)線程的調(diào)用堆棧,就可以知道沒(méi)有響應(yīng)的線程到底在后臺(tái)做些什么事情,或者等待著什么資源
jstack命令格式如下:
jstack [option] vmid
option選項(xiàng)的合法值與具體含義如下:
例子如下:
在JDK1.5中,java.lang.Thread類新增了一個(gè)getAllStackTraces()方法用于獲取虛擬機(jī)中所有線程的StackTraceElement對(duì)象。使用這個(gè)方法可以通過(guò)簡(jiǎn)單的幾行代碼就完成了jstack的大部分功能。在實(shí)際項(xiàng)目中不妨調(diào)用這個(gè)方法做個(gè)管理員頁(yè)面,可以隨時(shí)使用瀏覽器
來(lái)查看線程堆棧,例子如下:
package hjc.test9b;
import java.util.Map;
/**
* Created by cong on 2018/4/5.
*/
public class Main {
public static void main(String[] args) {
Map<Thread, StackTraceElement[]> m = Thread.getAllStackTraces();
for (Map.Entry<Thread, StackTraceElement[]> en : m.entrySet()){
Thread t = en.getKey();
StackTraceElement[] v = en.getValue();
System.out.println("The Thread name is :" + t.getName());
for (StackTraceElement s : v){
System.err.println("/t" + s.toString());
}
}
}
}
運(yùn)行結(jié)果如下:
7.JConsole:Java監(jiān)控與管理控制平臺(tái)。
JConsole是一種基于JMX的可視化監(jiān)視,管理工具。通過(guò)JDK/bin目錄下的jconsole.exe來(lái)啟動(dòng)JConsole
雙機(jī)她進(jìn)去,可以看到主界面包括概述,內(nèi)存,線程,類,VM摘要,MBean6個(gè)頁(yè)面
對(duì)線程的監(jiān)控例子如下:
死鎖代碼樣例:
這段代碼開(kāi)了200個(gè)線程去分別計(jì)算1+2以及2+1的值,造成死鎖的原因是Integer.valueOf()方法基于減少對(duì)象創(chuàng)建次數(shù)和節(jié)省內(nèi)存的考慮,[-128,127]之間的數(shù)字會(huì)被緩存,當(dāng)valueOf()方法傳入?yún)?shù)在這個(gè)范圍之內(nèi),將直接返回緩存中的對(duì)象。也就是說(shuō)
代碼中調(diào)用200次Integer.valueOf()方法一共就返回了兩個(gè)不同的對(duì)象。假如在某個(gè)線程的兩個(gè)synchronized塊之間發(fā)生了一次線程切換,那就會(huì)出現(xiàn)線程A等線程B持有的Integer.valueOf(1),線程B又等待著被線程A持有的Integer.valueOf(2),結(jié)果大家都跑不下去。
出現(xiàn)思索后,點(diǎn)擊Jconsole線程面板的檢測(cè)到死鎖的按鈕,將出現(xiàn)一個(gè)新的死鎖標(biāo)簽。如下圖:
>>>>閱讀全文
關(guān)鍵詞:故障,處理,工具,筆記,虛擬,性能