tags: java, troubleshooting, monitorhtml
一句話歸納:java應用監測,爲何?監測什麼?如何監測?本文爲你解答。java
java開發人員都知道,啓動java應用使用的是java
(class
文件)或java -jar
(jar
或war
包)命令。而java
命令其實就是啓動一個java虛擬機(JVM
),程序就是運行在JVM
上,JVM
負責類加載,運行時區域堆棧分配等工做,而堆棧分別用於程序中的對象及線程使用,分別影響的系統的cpu及內存,若是程序涉及文件或數據讀寫,還會影響系統的IO。所以,一個java應用啓動後,若是不對它所佔用的資源狀況進行監測,無疑於一架飛機起飛了,卻沒有儀表盤,這種飛機估計沒有人敢坐。所以,做爲開發人員,得清楚應用啓動後的運行狀況,並可以對應用運行情況進行監測,如此,才能及時預測有可能發生的問題進行及時修正或發生問題後能夠更快,更好地找到緣由所在,進而解決。可喜的是,程序自己,java工具和第三方工具,都爲咱們提供了不少監測java應用的方法,所以,做爲java開發人員,有必要對它們作一個系統的瞭解,以便於在實際應用中(特別是在生產環境中)更從容,更有效率的處理問題。linux
一個java應用運行起來,若出現問題,咱們第一反應確定是查看日誌,查看一下具體是報什麼錯,若沒有報錯,只是運行很慢,或者只是暫時尚未報錯,那咱們須要監測什麼內容呢?這一節,對比咱們平時使用操做系統,來看看對於java應用,須要監測什麼內容。ios
對於咱們平時使用的操做系統,如windows
,linux
系統,出現應用打開緩慢,系統響應緩慢,通常就是先查看系統的cpu運行和內存使用狀況,找出佔用資源高的進程,定位緣由,在windows
,直接在任務管理器-->性能
中查看,以下圖。windows
在linux
,可使用top
,free
,df
,iostat
等命令進行查看,以下圖。數組
在平常的運維過程當中,也是對系統的磁盤使用、IO、CPU、內存、網絡等狀況進行監測,爭取及時發現佔用資源高的進程,定位問題而後處理。tomcat
相對於操做系統,java應用須要監測的內容也有相似的地方,如佔用的cpu狀況,內存狀況,其中,會包含java應用的JVM參數,堆佔用狀況,線程運行狀態,類加載狀況,垃圾回收(GC
)狀況。至於爲何須要監測這些內容,就須要對java的虛擬機(JVM)有必定的瞭解,因爲本文JVM涉及內容較多,後面有機會再對JVM進行詳細講解,這裏能夠對java的JVM體系做一個簡要介紹,以便於讀者對後面章節的理解。見下圖:安全
當java運行一個應用,就會生成一個JVM的實例,而java應用則運行於此JVM實例中,當應用退出,JVM實例也會關閉。啓動多個java應用,也會啓動多個JVM實例,它們不會相互影響(固然,它們都會佔用系統的資源)。網絡
虛擬機主要有三大模塊,一個類加載子系統(Class Loader Subsystem
,負責加載類),一個執行引擎(Execution Engine
,負責執行類的方法指令和垃圾回收),一個運行時數據區(Runtime Data Areas
,負責存放程序運行時的數據)。oracle
其中運行時數據區分爲方法區(存儲如類信息,方法信息,引用,常量池等),堆(存儲類實例對象和數組),java棧(以棧方式存放以幀爲單位保存線程的運行狀態幀),本地方法棧(跟本地方法相關的數據區),程序計數器(每個線程都有它本身的程序計數器,表示下一條將被執行指令的「地址」)。
java應用啓動流程就是經過類加載子系統加載相關的類,而後把相關數據如類信息,方法等存到方法區的棧中,實例化相關的類,同時把實例對象存儲在堆中,程序運行位置則是每一個線程使用計數器來指定。方法區和堆是線程共享的,程序計數器及Java棧是線程私有的。
運行時數據區是java應用運行時的監測區域,其中各個區域的內存狀況,特別是堆的內存使用狀況,是重點區域。堆還會分年輕代、年老代及 Metaspace
,垃圾回收器會進行分代回收。經過它的回收狀況監測,能夠檢測到是否存在內存泄漏,而java棧則與線程有關,線程的運行狀態又與CPU相關,所以java棧的監測能夠知道CPU佔用過大的問題,同時方法區和java棧的佔用內存大小也是一個監測的指標。
通過上面的描述,咱們大概已經知道一個java應用啓動後,咱們爲何須要監測java應用以及須要監測哪些東西。那落實到實際應用中,該如何進行監測呢?下面經過對java應用監測工具及方法進行一個概要介紹,後續將會以系列文章的形式,對各個監測工具及方法進行詳細介紹。
按監測工具的監測方式,主要分爲如下四大類:
程序內置監測就比較簡單,在初學java時,最經常使用的就是使用System.out.println()
把本身想要輸出的內容輸出,在開發階段也有人喜歡這樣,一方面能夠輸出業務內容,監測功能的正常與否,另外一方面能夠輸出系統屬性System.getProperties()
及System.getProperty()
。固然,如今更多的使用日誌框架進行輸出,並把日誌按級別輸出到文件中,如log4j
及logback
。對於Spring Boot
應用,還可使用actuator
來監測程序運行狀況。tomcat
容器自身也帶有監測頁面。此類監測主要特色是程序內置,而且經過日誌輸出來監測,開發人員相對比較熟悉了,通常來講在開發和測試階段比較經常使用,而生產環境下,日誌通常是error
級別或者因爲安全考慮,自帶的一些監測頁面有可能會關閉。所以,此類監測再也不細說。
在jdk的安裝目錄下的的bin目錄,已經提供了多種命令行監測工具,以便於開發人員和運維人員監測java應用,同時方便開發及運維人員對問題進行診斷,所以,此類工具是java應用監測的重要手段。通常來講,經常使用的命令行工具包括jps
,jinfo
,jmap
,jstack
,jstat
,其中
jps
查看java進程IDjinfo
查看及調整虛擬機參數jmap
查看堆(heap)使用狀況及生成堆快照jstack
查看線程運行狀態及生成線程快照jstat
顯示進程中的類裝載、內存、垃圾收集等運行數據。經過這些工具,基本上能夠了解java應用的內存變化狀態,線程運行狀態等信息,進而爲應用監測及問題診斷提供依據。後面的文章將會對這些工具進行詳細描述。
除了命令行工具,在windows平臺下,jdk還提供了可視化監測工具,以更直觀,更方便的方式對java應用運行情況進行監測。這兩款工具分別是jconsole
和jvisualvm
,在jdk下的bin目錄下能夠找到。它們都可監測本地及遠程的java應用,包括堆使用狀況,線程使用,cpu使用,類加載狀況,gc狀況,jvisualvm
還能夠生成相應的堆和線程快照,同時還可使用相應的插件,以便於進一步分析。後面的文章將會對這兩款工具的使用進行詳細描述。
除了java自帶的工具,一些第三方的工具也是監測及分析診斷,性能調優的利器,包括MAT
,BTrace
及Arthas
。其中
MAT
是eclipse
的內存分析插件,經過MAT
能夠對dump出來的堆快照進行分析,而且輔助分析內存泄露緣由,快速的計算出在內存中對象的佔用大小,垃圾收集器的回收工做狀況,並能夠經過報表直觀的查看到可能形成這種結果的對象。BTrace
是是sun推出的一款Java 動態、安全追蹤(監控)工具,能夠在不停機的狀況下監控系統運行狀況,而且作到最少的侵入,佔用最少的系統資源。特別適用在生產環境下對java應用進行監測,問題排查。Arthas
是阿里開源的在線Java診斷工具,一樣能夠在不停機狀況監控系統,包括內存狀況,線程狀況,GC狀況,運行時數據,也能夠監測方法參數、返回值,異常返回等數據,堪稱神器,在生產環境下使用很是方便。後面的文章將會對這三款第三方工具的使用進行詳細描述。
但願經過本系列的文章,讓你們能夠對java的應用監測技術有所瞭解,熟悉各類監測工具,以便於在遇到線上問題(特別是性能問題,oom問題等),能夠從容面對及處理。
https://docs.oracle.com/javase/specs/jvms/se8/html/index.html
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/
https://www.cnblogs.com/java-my-life/archive/2012/08/01/2615221.html