如何更深入地進行系統(tǒng)性能分析與優(yōu)化呢?
一般情況下,我們會通過調(diào)整參數(shù)來提高系統(tǒng)性能,如線程池大小、連接池大小或者ORB池等,也可以利用IHS實現(xiàn)靜態(tài)文件分離,以上方式都是通過配置調(diào)整,利用并行或壓力分離等方式實現(xiàn)對系統(tǒng)的優(yōu)化。我們還可以更換運算率更高的服務(wù)器,或者增加更多的物理服務(wù)器,通過硬件角度擴展達到性能調(diào)優(yōu)的目的,但這種硬件擴容調(diào)優(yōu)方式會使得項目的成本費用會大大增加,且優(yōu)化成效還不一定能達到期待值。當然,在以數(shù)據(jù)庫操作為主的業(yè)務(wù)系統(tǒng)還可以調(diào)整數(shù)據(jù)庫的參數(shù),例如內(nèi)存占用比率,增加命中,緩沖等的優(yōu)化。
但以上這些優(yōu)化方式都是從系統(tǒng)周邊環(huán)境的角度進行考慮的,如果我們不了解我們的業(yè)務(wù)應用代碼在JVM中是如何運行的,又或者各執(zhí)行的請求是如何進行處理的,其處理的過程及處理步驟處于什么狀態(tài)下,就盲目開展優(yōu)化工作,就有了點瞎子過河——摸不著邊的意思了。
因此,盡可能收集更多的信息,會讓我們的優(yōu)化工作事半功倍!
除了自己實現(xiàn)線程請求監(jiān)控記錄外,我們還可以通過Javacore文件來進行線程轉(zhuǎn)儲。通過采集和分析Javacore,了解JVM的運行情況,可以使我們更清晰地了解系統(tǒng)的整體運行情況,幫助我們判斷系統(tǒng)是否運行正常,或是在繁忙時存在哪些隱患。
一、什么是Javacore?
Javacore是Java應用程序在某一時間的文本表示形式,也可理解為Java Dump(通常稱為Thread Dump)的線程轉(zhuǎn)儲文件。該文件記錄了整個JVM的運行情況,包含線程、垃圾回收、JVM運行參數(shù)、內(nèi)存地址等信息。JVM的許多問題都可以用這個文件進行診斷,其中比較典型的包括線程阻塞、CPU使用率過高、JVM Crash、堆內(nèi)存不足和類裝載等問題。
Javacore文件通常以*.txt方式顯示,名稱格式主要是以Javacore為頭,加上日期號、產(chǎn)生的時間號、當時的線程編號,如: Javacore.20100719.003424.299228.txt.
我們可以通過以下幾種方式獲取Javacore:
1. 向操作系統(tǒng)發(fā)送一個中止的signal
AIX和Linux:SIGQUIT,kill -3 PID
Windows:CTRL+Break,DrAdmin in WAS環(huán)境
2. 在Java的執(zhí)行代碼中使用JavaDump()方法
com.ibm.jvm.Dump.JavaDump() 方法促使JVM dump
發(fā)布ProblemDiagnosticsLabToolkit應用包,通過可視化頁面直接生成相關(guān)文件。
3. 系統(tǒng)在異常時自動拋出
一個嚴重的本地調(diào)用出錯(非Java的異常)
JVM堆的大小被使用完了
OutOfMemory 錯誤
二、Javacore描述了什么內(nèi)容?
在Javacore文件的幫助下,我們就可以更好地分析系統(tǒng)運行情況,在系統(tǒng)出現(xiàn)死鎖,或者內(nèi)部錯誤、中間件等問題時,我們都可以通過Javacore進一步深入分析。我們可以在Javacore文件里找到以下相關(guān)信息:
JVM的參數(shù)啟動參數(shù)、Jdk版本
JVM堆大小
JVM產(chǎn)生原因、產(chǎn)生時間(可手動獲取,可系統(tǒng)拋出)
全局垃圾回收次數(shù)、分配失敗次數(shù)、內(nèi)存溢出時,最后一次詳細的垃圾回收記錄
JVM堆內(nèi)存地址信息
JVM中,所有線程執(zhí)行情況(包含應用程序內(nèi)部執(zhí)行線程,容器線程,垃圾回收線程,定時線程,線程池線程,頁面請求轉(zhuǎn)發(fā)線程等多種線程信息)
已裝載入JVM中的類的信息
如下表:
序號 | 描述 | 例子 |
1 | JAVA產(chǎn)生的原因 產(chǎn)生時間 產(chǎn)生的線程號 JDK版本 JVM堆大小 空間堆大小 已分配的堆大小 |
|
2 | JVM堆對象占用比例信息 | |
3 | 整體線程的狀態(tài),各占比例情況 | |
4 | 主要線程類型與其線程數(shù),及在整個容器中所占用的比例 | |
5 | 其他相關(guān)信息 | …… |
三、如何分析Javacore?
我們可以通過Javacore提供的信息對JVM進行一個全面的分析,除了了解垃圾回收情況、JVM相關(guān)配置信息外,分析重點可放在線程執(zhí)行情況上,分析哪些線程在等待,哪些在執(zhí)行,以便快速縮小問題范圍。
(打開Javacore文件,龐大的字符串使得我們查找信息十分不便,此時我們可以利用IBM Thread and Monitor Dump Analyzer for Java工具分析,該工具可以讓我們清晰的分析Javacore文件)。
在IBM Thread and Monitor Dump Analyzer for Java工具中,請求線程可分為以下幾種狀態(tài):
死鎖,Deadlock(重點關(guān)注)
執(zhí)行中,Runnable(重點關(guān)注)
等待資源,Waiting on condition(重點關(guān)注)
等待監(jiān)控器檢查資源,Waiting on monitor
暫停,Suspended
對象等待中,Object.wait()
阻塞,Blocked(重點關(guān)注)
停止,Parked
在整個分析過程中,我們需要根據(jù)問題分析線程的運行的情況(如該Javacore是什么時候生成的,是內(nèi)存溢出,還是系統(tǒng)繁忙時),查看不同狀態(tài)的線程的執(zhí)行堆棧,分析堆棧找到其中屬于系統(tǒng)應用的代碼可進一步縮小問題點(在版本穩(wěn)定的中間件里,我們分析問題一般先從應用代碼入手,了解是哪些業(yè)務(wù)代碼觸發(fā)了問題)。我們要了解線程狀態(tài)具體的意思,線程中的堆棧代碼,整個容器的各個類型線程的情況,結(jié)合這些信息進行深入的分析。
ü Deadlock:死鎖線程,一般指多個線程調(diào)用間,進入相互資源占用,導致一直等待無法釋放的情況。
ü Runnable:一般指該線程正在執(zhí)行狀態(tài)中,該線程占用了資源,正在處理某個請求,有可能正在傳遞SQL到數(shù)據(jù)庫執(zhí)行,有可能在對某個文件操作,有可能進行數(shù)據(jù)類型等轉(zhuǎn)換。
ü Waiting on condition:等待資源,如果堆棧信息明確是應用代碼,則證明該線程正在等待資源,一般是大量讀取某資源,且該資源采用了資源鎖的情況下,線程進入等待狀態(tài),等待資源的讀取。又或者,正在等待其他線程的執(zhí)行等。
ü Blocked:線程阻塞,是指當前線程執(zhí)行過程中,所需要的資源長時間等待卻一直未能獲取到,被容器的線程管理器標識為阻塞狀態(tài),可以理解為等待資源超時的線程。這種情況在was的日志中,一般可以看到CPU饑渴,或者某線程已執(zhí)行了XX秒的信息。
在了解了以上線程狀態(tài)的具體意思后,我們就可以結(jié)合這些信息更進一步分析線程問題。
在內(nèi)存溢出時,分析Javacore文件中的線程內(nèi)容,可以采用自下而上的分析方法。首先查看有多少線程被設(shè)置了Blocked狀態(tài),這些線程是在執(zhí)行什么請求,并且到了堆棧最后一步在等待什么資源,將其分類記錄下來;查找到這些Blocked線程等待的執(zhí)行線程編號,在Javacore中,繼續(xù)查找該線程,分析其堆棧與狀態(tài)與監(jiān)控器的記錄的信息。一般這些線程會處于Waiting on condition狀態(tài),因為這些線程也是因為資源遲遲未獲取到或者執(zhí)行時間過長一直處于等待狀體,進一步導致隊列中其他需要訪問這些資源的線程都被設(shè)置為Blocked狀態(tài)。在找到線程后,我們就可以初步將問題縮小到哪些業(yè)務(wù)應用請求存在問題,是哪一個類與哪一行代碼,其等待的資源是什么。結(jié)合這些信息詳細分析業(yè)務(wù)代碼,或者根據(jù)這些問題到IBM網(wǎng)站中,查找對應版本的中間件是否存在同樣的問題,如有,則可以考慮打補丁升級。
一個Javacore描述的是在一個時間片段中的JVM的運行情況,這些信息相對來說是有限的,為了更進一步分析與定位問題,我們可以采集連續(xù)多個時間片段的Javacore,如間隔30秒或者幾分鐘的Javacore。分別對這些Javacore進行分析,以求更加清晰JVM在該時間段內(nèi)的運行情況,或者出現(xiàn)阻塞問題的線程及其相關(guān)線程的的執(zhí)行情況,從而準確定位問題。
在整個性能優(yōu)化過程中,學會如何分析Javacore是十分關(guān)鍵的一步。通過切面,對JVM中所運行的線程及堆棧進行全面分析,可以讓我們順利而有方向性地開展性能調(diào)優(yōu)工作,并使優(yōu)化工作更加簡單快捷。