1. 程式人生 > >【開發工具】JAVA效能分析:5、超詳細的JProfilerCPU分析(官方中文版)

【開發工具】JAVA效能分析:5、超詳細的JProfilerCPU分析(官方中文版)

CPU Profiling——CPU分析

當JProfiler測量方法呼叫的執行時間及其呼叫堆疊時,我們稱之為“CPU分析”。該資料以各種方式呈現。根據您嘗試解決的問題,一個或另一個簡報將是最有幫助的。預設情況下不記錄CPU資料,您必須開啟CPU記錄才能捕獲有趣的用例。

一、取樣與儀表——Sampling versus instrumentation

測量方法呼叫可以使用稱為“取樣”和“檢測”的兩種不同技術來完成,每種技術都有優點和缺點:通過取樣,JVM定期停止並檢查當前的呼叫堆疊。使用檢測,可以修改所選類的位元組碼以跟蹤方法的進入和退出。

處理取樣資料時,比較後續取樣。它們的公共呼叫堆疊顯示了在兩個樣本之間的整個時間內可能執行的方法。隨著大量樣本,出現統計上正確的影象。取樣的優點是開銷非常低。不需要修改位元組碼,取樣週期遠大於方法呼叫的典型持續時間。缺點是你錯過了短期執行的方法呼叫,你無法確定方法呼叫計數。如果您正在尋找效能瓶頸,這無關緊要,但如果您試圖瞭解程式碼的詳細執行時特性,則可能會很不方便。

 

另一方面,如果檢測了許多短期執行方法,則儀表會引入很大的開銷。由於時間測量的固有開銷,這種儀器會扭曲效能熱點的相對重要性,但也因為熱點編譯器以其他方式內聯的許多方法現在必須保持單獨的方法呼叫。對於花費較長時間的方法呼叫,開銷是微不足道的。如果您能找到一組主要執行高階操作的良好類,那麼檢測將增加非常低的開銷,並且可以優於取樣。此外,呼叫計數通常是重要的資訊,可以更容易地檢視正在發生的事情。

 

二、跟蹤樹——Call tree

跟蹤所有方法呼叫及其呼叫堆疊將消耗大量記憶體,並且只能保持很短的時間直到所有記憶體都耗盡。此外,直觀地掌握繁忙JVM中的方法呼叫次數並不容易。通常,這個數字是如此之大,以至於無法定位和跟蹤痕跡。

另一個方面是,如果收集的資料被聚合,許多效能問題才會變得清晰。通過這種方式,您可以瞭解方法呼叫對特定時間段內整個活動的重要性。對於單個跟蹤,您不瞭解您正在檢視的資料的相對重要性。

這就是為什麼JProfiler構建所有觀察到的呼叫堆疊的累積樹,用觀察到的時序和呼叫計數進行註釋。按時間順序排除,只保留總數。樹中的每個節點代表一個至少觀察過一次的呼叫堆疊。節點有子節點,表示在該呼叫堆疊中看到的所有傳出呼叫。

呼叫樹是“CPU檢視”部分中的第一個檢視,它是啟動CPU分析時的一個很好的起點,因為從起點到最細粒度的終點的方法呼叫之後的自上而下的檢視最容易瞭解。JProfiler按照總時間對子項進行排序,因此您可以首先開啟樹深度,以分析對效能影響最大的樹部分。

呼叫樹過濾器

如果呼叫樹中顯示了所有類的方法,則樹通常太深而無法管理。如果您的應用程式是由框架呼叫的,則呼叫樹的頂部將包含您不關心的框架類,並且您自己的類將被深埋。呼叫庫將顯示其內部結構,可能有數百個級別的方法呼叫,您不熟悉且無法影響。

此問題的解決方案是將過濾器應用於呼叫樹,以便僅記錄某些類。作為一個積極的副作用,必須收集更少的資料,並且必須對更少的類進行檢測,因此減少了開銷。

預設情況下,分析會話配置有常用框架和庫中的排除包列表。

當然這個列表是不完整的,所以你刪除它並自己定義感興趣的軟體包要好得多。事實上,儀器和預設過濾器的組合是如此不可取,JProfiler建議在會話啟動對話方塊中更改它。

過濾器表示式與完全限定的類名進行比較,因此com.mycorp. 匹配所有巢狀包中的類,例如com.mycorp.myapp.Application。有三種類型的過濾器,稱為“profiled”,“compact”和“ignored”。測量“分析”類中的所有方法。這就是您自己的程式碼所需要的。

在“緊湊”過濾器所包含的類中,僅測量對該類的第一次呼叫,但不顯示其他內部呼叫。“Compact”是你想要的庫,包括JRE。例如,在呼叫hashMap.put(a, b)時可能希望HashMap.put()在呼叫樹中看到但不多於它 - 除非您是地圖實現的開發人員,否則應將其內部工作視為不透明。

最後,根本沒有對“忽略”方法進行分析。由於開銷考慮,它們可能不適合儀器,或者它們可能只是在呼叫樹中分散注意力,例如在動態呼叫之間插入的內部Groovy方法。

手動輸入包容易出錯,因此您可以使用包瀏覽器。在啟動會話之前,程式包瀏覽器只能顯示已配置的類路徑中的程式包,這些程式包通常不會涵蓋實際載入的所有類。在執行時,包瀏覽器將顯示所有已載入的類。

為每個類從上到下評估已配置的過濾器列表。在每個階段,如果存在匹配,則當前過濾器型別可能會更改。什麼樣的過濾器從過濾器列表開始是很重要的。如果以“profiled”過濾器開頭,則類的初始過濾器型別為“compact”,這意味著僅分析顯式匹配。

 

a.*a.b.*a.b.c.*a.Aa.b.Ba.b.c.CDefault:123Result:d.Dprofiledcompactmatch

 

如果使用“緊湊”過濾器啟動它,則類的初始過濾器型別為“已分析”。在這種情況下,除了顯式排除的類之外,所有類都被分析。

 

a.*a.b.*a.b.c.*a.Aa.b.Ba.b.c.CDefault:123Result:d.Dprofiledcompactmatch

 

四、呼叫樹時間——Call tree times

要正確解釋呼叫樹,瞭解呼叫樹節點上顯示的數字非常重要。對於任何節點,總時間和自我時間有兩次是有趣的。自身時間是節點的總時間減去巢狀節點中的總時間。

通常,除了緊湊過濾類之外,自我時間很短。大多數情況下,壓縮過濾類是葉節點,總時間等於自身時間,因為沒有子節點。有時,緊湊過濾的類將呼叫一個分析類,例如通過回撥或因為它是呼叫樹的入口點,就像run當前執行緒的方法一樣。在這種情況下,一些未經編譯的方法消耗了時間,但未在呼叫樹中顯示。那個時間到達呼叫樹中第一個可用的祖先節點並且有助於緊湊過濾類的自我時間。

 

A: self time 1 msC: self time 3 msB: self time 2 msprofiledcompactB: self time 6 msX: self time 3 msY: self time 1 msactual call sequencefiltered call sequence

 

呼叫樹中的百分比條顯示總時間,但自我時間部分顯示為不同的顏色。除非在同一級別上的兩個方法被過載,否則顯示的方法沒有其簽名。有多種方法可以在檢視設定對話方塊中自定義呼叫樹節點的顯示。例如,您可能希望將自我時間或平均時間顯示為文字,始終顯示方法簽名或更改使用的時間刻度。此外,百分比計算可以基於父時間而不是整個呼叫樹的時間。

五、執行緒狀態——Thread status

在呼叫樹的頂部有幾個檢視引數,用於更改顯示的分析資料的型別和範圍。預設情況下,累計所有執行緒。JProfiler基於每個執行緒維護CPU資料,您可以顯示單執行緒或執行緒組。

在任何時候,每個執行緒都有一個關聯的執行緒狀態。如果執行緒已準備好處理位元組碼指令或當前正在CPU核心上執行它們,則執行緒狀態稱為“Runnable”。在尋找效能瓶頸時,該執行緒狀態很有用,因此預設選擇它。

或者,執行緒可以通過在監視器上等待,例如通過呼叫Object.wait()或 Thread.sleep()在這種情況下執行緒狀態被稱為“等待”。嘗試獲取監視器時阻塞的執行緒(例如在synchronized程式碼塊的邊界處)處於“阻塞”狀態。

最後,JProfiler添加了一個合成的“Net I / O”狀態,用於跟蹤執行緒等待網路資料的時間。這對於分析伺服器和資料庫驅動程式很重要,因為該時間可能與效能分析相關,例如用於調查慢速SQL查詢。

如果您對掛鐘時間感興趣,則必須選擇執行緒狀態“所有狀態”並選擇單個執行緒。只有這樣,您才能將時間與通過System.currentTimeMillis()程式碼中的呼叫計算的持續時間進行比較。

如果要將所選方法轉換為其他執行緒狀態,可以使用方法觸發器和“覆蓋執行緒狀態”觸發器操作,或者使用嵌入式或 注入式探針API中的ThreadStatus類來執行此操作。

六、在呼叫樹中查詢節點——Finding nodes in the call tree

有兩種方法可以在呼叫樹中搜索文字。首先,通過從選單呼叫View-> Find或直接開始鍵入呼叫樹來啟用quicksearch選項。按下後將突出顯示匹配項並提供搜尋選項 PageDown。使用ArrowUpArrowDown鍵可以迴圈顯示不同的匹配項。

搜尋方法,類或包的另一種方法是使用呼叫樹底部的檢視過濾器。在這裡,您可以輸入以逗號分隔的過濾器表示式列表。以“ - ”開頭的過濾表示式就像緊湊過濾器一樣,否則就像分析過濾器一樣。與過濾器設定一樣,初始過濾器型別確定預設情況下是否包含或排除類。

單擊檢視設定文字欄位左側的圖示可顯示檢視過濾器選項。預設情況下,匹配模式為“Contains”,但搜尋特定包時“Starts with”可能更合適。

七、呼叫樹上的不同檢視——Different views on the call tree

雖然所有測量都是針對方法執行的,但JProfiler允許您通過在類或包級別聚合呼叫樹來獲取更廣泛的視角。聚合級別選擇器還包含“Java EE元件”模式。如果您的應用程式使用Java EE,則呼叫樹將顯示在呼叫堆疊跨越Java EE元件邊界時拆分呼叫樹的其他節點。“Java EE元件”聚合級別將刪除所有方法節點,並僅在樹中保留元件節點。

檢視呼叫樹的另一種方法是樹對映。樹圖中的每個矩形表示樹中的特定節點。矩形區域與樹檢視中大小條的長度成比例。與樹形成對比,樹形圖為您提供樹中所有葉子的展平透檢視。如果您最感興趣的是樹的主要葉子,您可以使用樹形圖來快速找到它們而無需深入挖掘樹的分支。此外,樹形圖可以讓您全面瞭解葉節點的相對重要性。

通過設計,樹對映僅顯示葉節點的值。分支節點僅以葉節點巢狀的方式表示。對於具有重要自我值的非葉節點,JProfiler構造合成子節點。在下圖中,您可以看到節點A的自身值為20%,因此其子節點的總和為80%。為了在樹圖中顯示A的20%自身值,建立了總值為20%的合成子節點A'。它是葉節點和B1和B2的兄弟節點。A'將在樹圖中顯示為彩色矩形,而A僅用於確定其子節點B1,B2和A'的幾何排列。

樹圖節點的實際資訊顯示在工具提示中,當您將滑鼠懸停在樹形圖上時會立即顯示這些提示。這些數字對應於樹檢視模式中顯示的資訊。樹形圖顯示的最大巢狀深度為25個級別,其比例始終相對於當前顯示的節點。

更高的聚合級別以及樹形圖都是從方法級別的細節退一步並採用鳥瞰圖的方式。但是,當您找到特別感興趣的點時,您通常會希望返回到方法級別。如果選擇了某個節點並且您更改了方法聚合級別,則JProfiler會盡可能地保留呼叫堆疊。使用樹對映,上下文選單中的 Show in tree操作提供了一種返回呼叫樹的方法。

八、熱點——Hot spots

如果您的應用程式執行速度太慢,您希望找到大部分時間都佔用的方法。使用呼叫樹,有時可以直接找到這些方法,但通常不起作用,因為呼叫樹可以包含大量葉節點。

在這種情況下,您需要呼叫樹的反轉:所有方法的列表按其總自身時間排序,累計來自所有不同的呼叫堆疊,後面跟蹤顯示方法的呼叫方式。在熱點樹中,葉子是入口點,如main應用程式的run方法或執行緒的方法。從熱點樹中最深的節點,呼叫向上傳播到頂級節點。

回溯中的呼叫計數和執行時間不是指方法節點,而是指沿著此路徑呼叫頂級熱點節點的次數。理解這一點非常重要:粗略地看一下,您可以期望節點上的資訊量化對該節點的呼叫。但是,在熱點樹中,該資訊顯示節點對頂級節點的貢獻。所以你必須讀取這樣的數字:沿著這個倒置的呼叫堆疊,頂級熱點被稱為 n時間,總持續時間為t秒。

預設情況下,熱點是從自身時間計算的。您也可以從總時間計算它們。這對於分析效能瓶頸並不是很有用,但如果您想檢視所有方法的列表,則會很有趣。熱點檢視僅顯示減少開銷的最大方法數,因此您可能無法顯示所查詢的方法。在這種情況下,使用底部的檢視過濾器來過濾包或類。與呼叫樹相反,熱點檢視過濾器僅過濾頂級節點。熱點檢視中的截止值不是全域性應用的,而是針對顯示的類應用,因此在應用過濾器後可能會出現新節點。

九、熱點和過濾器——Hot spots and filters

熱點的概念不是絕對的,而是取決於呼叫樹過濾器。如果你根本沒有呼叫樹過濾器,那麼最大的熱點很可能總是JRE核心類中的方法,比如字串操作,I / O例程或集合操作。這樣的熱點不是很有用,因為你經常不直接控制這些方法的呼叫,也無法加快它們的速度。

為了對您有用,熱點必須是您自己的類中的方法或您直接呼叫的庫類中的方法。就呼叫樹過濾器而言,您自己的類在“分析”過濾器中,庫類在“緊湊”過濾器中。

解決效能問題時,您可能希望消除庫層,只檢視自己的類。您可以通過在熱點選項彈出視窗中選擇新增到呼叫配置檔案類單選按鈕,快速切換到呼叫樹中的該透檢視 。

十、呼叫圖——Call graph

在呼叫樹以及熱點檢視中,每個節點都可以多次出現,尤其是在遞迴呼叫時。在某些情況下,您對以方法為中心的統計資訊感興趣,其中每個方法僅發生一次,並且所有傳入和傳出呼叫都是可見的。這樣的檢視最好顯示為圖形,在JProfiler中,它稱為呼叫圖。

圖的一個缺點是它們的視覺密度低於樹的視覺密度。這就是為什麼JProfiler預設縮寫包名稱,預設情況下隱藏傳出呼叫的時間少於總時間的1%。只要節點具有傳出擴充套件圖示,您就可以再次單擊它以顯示所有呼叫。在檢視設定中,您可以配置此閾值並關閉包縮寫。

擴充套件呼叫圖時,它可能會很快變得混亂,特別是如果您多次回​​溯。使用撤消功能可以恢復圖形的先前狀態。與呼叫樹一樣,呼叫圖提供快速搜尋。通過鍵入圖表,您可以開始搜尋。

圖表和樹檢視各有優缺點,因此有時您可能希望從一種檢視型別切換到另一種檢視型別。在互動式會話中,呼叫樹和熱點檢視顯示實時資料並定期更新。但是,呼叫圖是根據請求計算的,並且在展開節點時不會更改。呼叫樹中的“在呼叫圖中顯示”操作計算新的呼叫圖並顯示所選方法。

無法從圖表切換到呼叫樹,因為以後資料通常不再具有可比性。但是,呼叫圖通過其View-> Analyze 操作提供呼叫樹分析,該操作可以顯示每個所選節點的累計傳出呼叫和回溯的樹。

呼叫樹,熱點檢視和呼叫圖的集合具有許多高階功能,這些功能將在不同章節中詳細說明。此外,還有其他高階CPU檢視單獨顯示