深刻理解JVM(七)——性能監控工具

前言html

  工欲善其事必先利其器,性能優化和故障排查在咱們大都數人眼裏是件比較棘手的事情,一是須要具有必定的原理知識做爲基礎,二是須要掌握排查問題和解決問題的流程、方法。本文就將介紹利用性能監控工具,幫助開發者更快更準的找到問題產生的根源。本文分爲三部分,第一部分將介紹在Linux環境下的經常使用監控工具,第二部分介紹Windows環境下的監控工具,第三部分將經過一個案例,介紹利用這些監控工具一步一步找出java應用程序的問題。java

Linux環境下的監控工具sql

  須要先聲明的是,下面介紹的部分工具其實在Liunx環境、Windows環境下均可以使用,只不過在不一樣的環境下使用什麼工具更合適。shell

  下面咱們想象這麼一個場景:有一天運維人員看到生產環境下的服務器負載升高、CPU飆升,內存佔用增大,請問接下來他該怎麼辦?可能有人會說,那就找到負載升高、CPU飆升。。的緣由啊,若是是應用程序形成的就把它kill掉。若是採用這種方法,問題可能會短期解決,但帶來的問題是應用在一段時間不可用,而且咱們沒有找到問題發生的根源,下次重啓後,問題依然會產生。那麼若是出現相似的問題,嚴格的排查流程是怎樣的呢?在回答這個問題以前,咱們先了解一下Linux上經常使用的幾個監控工具:windows

uptimecentos

[root@centos7_template ~]# uptime 10:31:42 up 4 days, 1:01, 1 user,load average: 0.02, 0.02, 0.05
10:31:42    //當前系統時間
up 4 days, 1:01 //持續運行時間,時間越大,說明你的機器越穩定。 
1 user  //用戶鏈接數,是總鏈接數而不是用戶數 
load average: 0.02, 0.02, 0.05  //系統平均負載,統計最近1,5,15分鐘的系統平均負載

該命令將顯示目前服務器持續運行的時間,以及負載狀況。性能優化

經過這個命令,能夠最簡便的看出系統當前基本狀態信息,這裏面最有用是負載指標,若是你還想查看當前系統的CPU/內存以及相關的進程狀態,可使用TOP命令。服務器

TOP運維

70NN3YT1%9[V1M5EU4{FPGQ

經過TOP命令能夠詳細看出當前系統的CPU、內存、負載以及各進程狀態(PID、進程佔用CPU、內存、用戶)等。從上面的結果看出該系統上安裝了MySQL、java,能夠看到他們各自的進程ID,假如這時Java進程佔用較高的CPU和內存,那麼你就要留心了,若是程序中沒有計算量特別大、佔用內存特別多的代碼,可能你的java程序出現了未知的問題,能夠根據進程ID作進一步的跟蹤。除了經過TOP命令找到進程信息之外,還能夠經過jdk自帶的工具JPS直接找到java程序的進程號。nosql

JPS

image

能夠看到jps命令直接羅列出了當前系統中存在的java進程,這裏第一個是jps命令本身的java進程,而另一個是我啓動的nosql監控工具進程。經過這種方法查詢到java程序的進程ID後,能夠進一步經過:

top -p 3618 // 這裏的3618就是上面查詢到的java程序的進程ID

image

經過此方法能夠準確的查看指定java進程的CPU/內存使用狀況。

除此以外,vmstat命令也能夠查看系統CPU/內存、swap、io等狀況:

VIBLT41${5HGEYJ}QZ)~T`T

上面的命令每隔1秒採樣一次,一共採樣四次。CPU佔用率很高,上下文切換頻繁,說明系統有線程正在頻繁切換,這多是你的程序開啓了大量的線程存在資源競爭的狀況。另外swap也是值得關注的指標,若是swpd太高則可能系統能使用的物理內存不足,不得不使用交換區內存,還有一個例外就是某些程序優先使用swap,致使swap飆升,而物理內存還有不少空餘,這些狀況是須要注意的。

查看系統指標,還有一個第三方工具:pidstat,這個工具仍是很好用的,須要先安裝:

yum install sysstat

image

該命令監控進程id爲3618的CPU狀態,每隔1秒採樣一次,一共採樣四次。「%CPU」表示CPU使用狀況,「CPU」則表示正在使用哪一個核的CPU,這裏爲0表示正在使用第一個核。若是還要顯示線程ID,則可使用:

pidstat -p 3618 -u -t 1 4

若是要監控磁盤讀寫狀況,這可使用:

image

pidstat還有其餘的參數,能夠經過pidstat --help獲取,再次再也不贅述。

下面再介紹幾個JDK自帶有用的工具:jps、jstat、jmap、jstack

jps:上面咱們已經使用過了,他能夠羅列出目前再服務器上運行的java程序及進程ID;

jstat:用於輸出java程序內存使用狀況,包括新生代、老年代、元數據區容量、垃圾回收狀況。

image

上述命令輸出進程ID爲3618的內存使用狀況(每2000毫秒輸出一次,一共輸出20次)

  • S0:倖存1區當前使用比例
  • S1:倖存2區當前使用比例
  • E:伊甸園區使用比例
  • O:老年代使用比例
  • M:元數據區使用比例
  • CCS:壓縮使用比例
  • YGC:年輕代垃圾回收次數
  • FGC:老年代垃圾回收次數
  • FGCT:老年代垃圾回收消耗時間
  • GCT:垃圾回收消耗總時間

jmap:用於輸出java程序中內存對象的狀況,包括有哪些對象,對象的數量。

jmap -histo 3618

上述命令打印出進程ID爲3618的內存狀況。但咱們經常使用的方式是將指定進程的內存heap輸出到外部文件,再由專門的heap分析工具進行分析,例如mat(Memory Analysis Tool),因此咱們經常使用的命令是:

jmap -dump:live,format=b,file=heap.hprof 3618

將heap.hprof傳輸出來到window電腦上使用mat工具分析:

{U[6FUIMFB%~8B~ZWC9C(RL

jstack:用戶輸出java程序線程棧的狀況,經常使用於定位由於某些線程問題形成的故障或性能問題。

jstack 3618 > jstack.out

上述命令將進程ID爲3618的棧信息輸出到外部文件,便於傳輸到windows電腦上進行分析。

Windows環境下的監控工具

Windows環境下的監控工具也有不少,可是本文主要推薦jvisualvm.exe、MemoryAnalyzer.exe,有了他們其餘工具幾乎不須要了。

jvisualvm.exe在JDK安裝目錄下的bin目錄下面,雙擊便可打開。

[(12G94WOFP`XLH1}BL[SD8

雙擊左側你須要監控的java程序便可對它進行監控,這個工具包括對CPU、內存、線程、類都作了監控,功能很是強大,上文中介紹的全部功能,其餘在這個工具上都已經有了。固然怎麼用、如何分析它須要花時間去一點點積累。

MemoryAnalyzer.exe:上文咱們已經提到,經常使用於分析內存堆使用狀況,也是很是強大的工具。詳細使用方法,這裏就再也不贅述,能夠下載下來嘗試一下。

上述介紹了基於Linux、Windows環境的監控工具,有了這些工具咱們就要利用他們作對應的事情,下面將經過一個簡單的案例,說明如何使用他們。

案例分析

首先經過上述的介紹,咱們對故障排查流程應該有了一個印象,這裏先梳理出來:

image

案例:

 一個java應用啓動之後,使用人員發現應用不可用,針對該現象咱們作如下分析排查:

一、首先查看服務器上的應用狀態。使用jps命令查詢當前在運行中的java進程:

image

這裏進程ID爲6400的java應用就是咱們剛啓用的,說明應用並無掛掉,還在運行中。

二、經過進程ID查詢所佔用的CPU、內存以及當前負載狀況,top -p 6400。

 

 

image

從以上結果看出該應用並無引發系統負載太高,CPU、內存也沒有出現異常狀況。

三、經過上述結果咱們推測由於內存緣由引發的故障可性能較小,因此咱們優先排查線程棧,使用jstack命令,導出線程棧。

jstack 6400 > stack.out

咱們將該文件傳輸出來便於查看。

D{1SED$N[6E`YTTO9CZH%SQ

查看線程棧能夠看出,主線程處於運行狀態,而子線程ThreadA、ThreadB、ThreadC、ThreadD一邊在等待一個鎖,同時又持有另一個鎖,其實看到這裏咱們基本推斷該應用程序存在死鎖,所以形成線程等待,應用不可用。經過以上棧的信息,咱們就能夠到程序代碼中詳細查看代碼了,而且修改bug解決此問題。

死鎖原理補充:

image

如圖所示,形成死鎖的緣由是線程之間存在相互制約的狀況,而任一線程都沒法繼續執行。

小結

  本文介紹了Linux、Windows環境下經常使用的監控工具,最後經過一個案例簡單說明故障排查的流程,怎麼使用監控工具找出應用故障的緣由。

相關文章
相關標籤/搜索