1. 程式人生 > >JAVA 005 問題定位和分析方法

JAVA 005 問題定位和分析方法

目錄

  問題

  問題定位

 

此文只大致介紹問題定位的粗略過程,關於系統內部的問題查詢,例如執行緒堆轉儲檔案,記憶體堆轉儲檔案,GC日誌的分析,以及Linux系統命令的使用及檢視介紹,在其它文章中介紹

 

問題

記憶體洩漏(記憶體無法釋放)

  程式中已動態分配的堆記憶體由於某種程式未釋放或無法釋放,造成記憶體的浪費,導致程式執行速度減慢甚至系統崩潰等驗證結果(無法釋放)(後果就是記憶體溢位)

記憶體溢位(記憶體不夠)

  程式執行要用到的記憶體大於虛擬機器能提供的最大記憶體

 

問題定位(指的是Linux環境下的問題查詢)

問題定位資料:執行日誌,異常堆疊,GC日誌,執行緒快照,堆轉儲快照

步驟

  1 先排除其它程式過渡佔用系統資源的情況

  2 排除"目標服務"(有問題的系統)本身佔用系統過渡的情況

  3 觀察"目標服務"(有問題的系統)內部的情況,排除掉各種故障型別

  4 應用伺服器監控及程式碼分析

 

排除其它程式過渡佔用系統資源(CPU,記憶體,磁碟,網路)

1 CPU檢查

  執行【top】命令檢查CPU(idel空閒)空閒較多,則排除其它程序佔用CPU過量的情況,否則根據CPU佔用率降序,檢視高CPU佔用率高的程序,確定為什麼此程序會佔用CPU高

2 記憶體檢查

  執行【free】命令檢查剩餘實體記憶體(-/+buffer/cache行的free)情況,剩餘實體記憶體較多,則排除佔用實體記憶體過量的情況,否則通過【vmstat -n 1】檢查【交換空間(作業系統中有講解幹嘛的)】(si/so換入換出)情況,多行(si/so)數值都為0,排除剩餘實體記憶體不足,(si/so)數值較多,說明存在較明細的記憶體不足問題,通過【top】,將程序按照實體記憶體大小佔用(RES)從大到小程序排序,檢視記憶體佔用率高的程序,確定為什麼此程序佔用記憶體高

3 IO檢查

  執行【iostat】檢查磁碟IO請求,磁碟讀寫量在預估之內,排除其它程序佔用磁碟IO過多的情況,磁碟讀寫量明顯超過推算,則找到大量讀寫磁碟的程序

4 網路IO

  執行【netstat -anop | grep tcp | wc -l】檢視各種狀態的TCP連線數量和,總數較少,則排除連線數佔用過多的情況,(怎樣統計每個程序的TCP連線數量)

關於如何找到大量讀寫磁碟的情況(【iotop】獲取每個程序的IO情況)

  通過【ls -l /proc/*/fd | grep 該裝置對映裝載到的檔案系統路徑】 檢視到哪個程序打開了該裝置的檔案,並根據程序身份,開啟的檔名,檔案大小等屬性判斷是否做了大量讀寫

  可以使用【pstack】取得程序的執行緒呼叫棧,或者【strace】跟蹤磁碟讀寫API來幫助確認某個程序是否在做磁碟做大量讀寫

 

排除目標服務佔用過濾系統情況

1 CPU檢查

  執行【top】,按照CPU使用從高到低的排序檢視程序,目標服務佔用的CPU較低,或者符合經驗預期,則排除目標服務CPU佔用過高的問題(否則,觀察執行緒級別的CPU)

  1.1 如果CPU分散到多個執行緒,而且每個執行緒佔用都不算高,則排除CPU佔用過高的問題

  1.2 如果CPU使用集中到一個執行緒或幾個執行緒,而且很高,則用【jstack pid > jstack.log】獲取目標服務中執行緒呼叫棧情況(top中看到的佔用CPU較高的執行緒的PID轉換成16進位制(字母用小寫),然後在jstack.log找到對應執行緒,檢查其邏輯)

    1.2.1 假如對應執行緒是純計算型任務(例如:GC,正則匹配,數值計算等)則排除CPU佔用過高問題,如果執行緒數佔用CPU總量過多,則需要限制執行緒數

    1.2.2 假如對應執行緒不是純計算型任務(例如:只是資料請求)則該執行緒CPU佔用過高,則可能發生了異常,例如:死迴圈,資料結構過大等

2 記憶體檢查

  執行【top】按照實體記憶體使用從高到低排序程序,評估目標服務佔的記憶體量是否在預期之內,如果在,則排除目標服務記憶體佔用過高的問題

 

目標服務內部檢查

  GC日誌分析

  執行緒堆轉儲檔案分析 【jstack -l PID】匯出 可以使用IBM JCA檢視

  記憶體堆轉儲檔案分析 【jmap -heap:format=b pid 格式】 《=1.5版本 【jmap -dump:format=b,file=filename pid】 >1.6 可以使用MAT進行分析

 

應用伺服器監控及程式碼分析

  1 入口 如http連線池之類,資料來源方向的相關配置,比如:連線數限制,超時時間,連接回收策略

  2 內部 處理請求的各項資源,比如:執行緒數,執行緒排程

  3 出口 向後端互動的各項資源,比如:資料庫連線池的配置