程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> IBM的Java診斷,第3部分

IBM的Java診斷,第3部分

編輯:關於JAVA

使用面向 Java 的 Lock Analyzer 診斷同步和鎖問題

減少鎖的爭用並提高性能

簡介:面向 Java™ 的 IBM® 鎖分析器可從 alphaWorks 獲得,可對運行中的 Java 應用 程序進行實時鎖監視。鎖爭用會降低應用程序性能,該工具會突出顯示發生鎖爭用的線程。開發人員可以 使用該信息修改其應用程序以減少鎖爭用,從而提高性能。 本文介紹了面向 Java 的 IBM 鎖分析器,介 紹了其構建的基礎架構並針對該工具的未來發展方向進行了思考。

當今很多 Java 應用程序都通 過使用線程來利用該語言的功能,從而支持並發編程。很多線程可以共享相同的數據對象,但是如果應用 程序中控制線程的部分設計得不好,則您可能會遇到鎖爭用問題從而降低性能。

例如,在多線程應用程序中,如果多個線程訪問相同的資源進行讀寫訪問, 則可能會出現線程同步問 題。如果一個線程嘗試讀取某個文件,而另一個線程 對其進行寫訪問,則可能會損壞數據。為了解決這 個問題,Java 語言允許一個線程獲得對對象的專有鎖, 從而防止其他任何線程訪問它。一旦該線程完成 對該對象的處理之後,便釋放該對象,以便 其他線程可以進行訪問。但是,如果應用程序沒有進行過精 心設計,則這種機制可能會導致更高級別的爭用。

如果一個鎖正在使用中,而另一個線程嘗試獲取它,這時會發生鎖爭用。 如果鎖被頻繁獲得和/或持 有時間較長,則可能會發生更高級別的爭用。 更高級別的鎖爭用(很多線程嘗試訪問它)將成為系統中 的瓶頸, 因為每個運行的線程將暫停執行,直到它所需的鎖變為可用為止, 這樣便限制了應用程序的性 能。

使用 JLA 防止出現鎖問題

面向 Java 的 IBM 鎖分析器 (JLA) 是 alphaWorks 中的新工具,它可以 在運行 IBM 提供的 Java SDK 或 JRE 版本 5.0 或更高版本的的任何平台上運行, 對活動應用程序執行鎖分析,以突出顯示線程 的活動並且提供對鎖爭用頻率的深入洞察。該視圖可以幫助解決鎖爭用問題以及性能問題。

JLA 一邊運行現有的 Java 應用程序,一邊收集該應用程序的所有鎖信息。記錄每個鎖及其詳細信息 ,如保持的時間、是否爭用以及它阻塞線程嘗試獲得它的時間百分比。該工具由運行時庫和前端圖形用戶 界面組成,前者必須在啟動所要監視的應用程序時加載,後者可以顯示結果和性能分析。

JLA 設計詳細信息

JLA 由以下兩個程序包組成:

JLAagent。該程序包與平台有關,由特定於平台的庫文件和一組打包成 JAR 的 Java 類組成,它提供 與 Java 虛擬機 (JVM) 的連接以收集有關運行的應用程序的鎖統計信息。

JLAGui。該程序包是使用 Swing 編寫的,它與平台無關,提供圖形用戶界面。

JLAagent 中的本地庫是用 C 編寫的並且使用 Java 虛擬機工具界面 ( Java Virtual Machine Tool Interface,JVM TI)。該界面提供方法控制在 JVM 中運行的應用程序的執行。通過該界面,您可以利用 IBM 發布的 JVM 中可用的功能收集線程統計信息。還可以通過對您要分析的 Java 應用程序的啟動命令 進行修改,讓 JVM 在啟動時加載此本地庫。然後本地庫使用與它一起打包的 Java 類創建一個平台 MBean 服務器,該服務器提供允許 JLAGui 連接 JLAagent 的機制。

啟動 MBean 服務器之後, JLAGui 可以通過將該服務器導航到本地庫中,然後導航到運行的 JVM 中 ,從而請求運行的應用程序的鎖統計信息。由於 JLAagent 和 JLAGui 通過 MBeans 連接,因此它們沒有 必要在同一機器上運行;JLAGui 還可以從網絡上的任意位置連接到 MBean 服務器。

運行 JLA

若要運行 JLA,您必須首先為您的應用程序配置 JLAagent。 然後您才可以啟動 JLAGui 開始監視鎖 性能。如果您尚未這樣做, 請 下載 JLA 以便您可以跟隨本文的操作。

配置應用程序以使用 JLA

有很多版本的 JLAagent,IBM 提供的 JRE 支持的每個平台使用一個版本;您必須確保使用的 JLAagent 與您要監視的應用程序將運行的平台相對應。如果您使用了錯誤版本的 JLAagent,則嘗試監視 的應用程序將無法加載並且將崩潰。根據將要啟動它的 JRE 的基礎架構,每個 JLAagent 程序包都具有 一個名稱。

在運行所要監視的應用程序的計算機上,將 JLAagent 程序包解壓縮到某個目錄。將該目錄添加到 Java 類路徑和系統路徑。屬性文件名為 JLAtiagent。屬性包含在該程序包中;它包含有關啟動 MBean 服務器的連接信息。如果您想修改默認值,可以編輯該屬性。

若要為將進行分析的應用程序加載 JLAagent,請修改該應用程序的啟動命令。 添加 - agentlib:JLAtiagent 參數以便它加載本地庫, 將添加的 JLAtiagent.jar 添加到類路徑, 並指定 JLAtiagent.properties 文件的位置。

例如,啟動命令 java dummy.class 將需要進行如下修改:

java -Dcom.sun.management.config.file=JLAtiagent.properties 
    -agentlib:JLAtiagent -cp .;JLAagent.jar dummy.class

如果此時出現異常,請進行檢查以確保使用正確的 JLAagent 版本。如果一切正常,將會在命令行上 顯示消息 JLA 客戶機正在注冊 MBeanServer。

此時,JLAagent 已經指導 VM 開始記錄鎖詳細信息,即使 JLAGui 未運行也是如此。這意味著當啟動 JLAGui 時,您將能夠查看整個應用程序生命周期中的鎖統計信息。

JLAGui

您可以使用以下命令啟動 JLAGui:

java -jar JLAGui.jar

默認情況下, JLAGui 將查找在本地主機端口 1972 上運行的 MBean 服務器;同樣不需要指定這些值 。但是如果您想使用不同的值,則可以在命令行上修改主機或端口值,如表 1 所示:

表 1. JLAGui 的連接選項

設置 默認值 說明 -Dcom.ibm.jla.port 1972 需要匹配 JLAtiagent 使用的 com.sun.management.jmxremote.port 值 -Dcom.ibm.jla.hostname 本地主機 如果想監視在遠程機器上運行的應用程序,可以設置為 IP 地址或有效的主機名

當啟動 GUI 時,它將嘗試通過機器上運行的 MBean 服務器以及在啟動選項中指定的端口號連接到代 理程序。 如果連接成功,則圖 1 中的屏幕將顯示:

圖 1. 初始 JLA 屏幕

如果連接未成功,則會顯示錯誤消息,並提供 GUI 嘗試連接的詳細信息。仔細查看錯誤消息以確保連 接正確。如有必要,您可以關閉 GUI,然後用修改後的命令行選項重新啟動。您還可以進行檢查以確保要 分析的應用程序正在運行附帶的本機代理程序。

單擊 Create Report 按鈕即可創建正在監視的應用程序當前線程統計信息的快照報告。您將看到三個 面板(參見圖 2),它們顯示 Java 監視程序(應用程序創建的那些監視程序)、系統監視程序(VM 創 建的那些監視程序)以及摘要報告頁。應用程序創建或使用的任何監視程序在表和圖中都有一個條目。每 個監視程序只有一個條目可見,即使有多個線程訪問它也是如此。將在監視程序級別而不是線程級別記錄 該數據。

圖 2. JLA 報告示例

每一列的高度基於慢鎖計數的值,它與圖中的所有列有關。當請求的監視程序已經被另一個線程擁有 並且請求線程被阻塞時會發生緩慢計數。每個條狀圖形的顏色基於 %MISS 列的值(參見表 2),從紅色 (100%) 逐漸過渡到黃色 (50%),並且最終變為綠色 (0%)。紅色條表示每次請求監視程序時線程都會阻塞 ,而綠色條表示線程從不阻塞。對圖進行快速掃描將顯示執行得不太好的那些監視程序。

表 2 解釋報告表中各列值的說明:

表 2. 報告表圖例

列名 說明 %MISS 當請求的線程被阻塞以等待監視程序時總 gets(獲取)的百分比。 GETS 成功獲取的總數。 NONREC 非遞歸獲取的總數。該數包括 SLOW gets。 SLOW 非遞歸獲取(導致阻塞請求線程以等待釋放監視程序)的總數。NONREC 中包含該數。 REC 遞歸獲取的總數。遞歸獲取表示請求的線程已經擁有監視程序 。 TIER2 支持三層自旋鎖的平台上,層 2(內部自旋循環)迭代的總數。 TIER3 支持三層自旋鎖的平台上,層 3(外部線程讓步循環)迭代的總數。 %UTIL 監視程序持有時間除以時間間隔。必須打開持有時間計數。 AVER_HTM 監視程序的平均持有時間;不包括遞歸獲取,因為遞歸獲取時已經擁有監視程序。 MONITOR NAME 監視程序名稱,如果不知道名稱,則為 NULL(空白)。

運行中的 JLA

一個簡單的應用程序示例將幫助您了解如何使用 JLA 幫助查找鎖爭用的區域。假設一個應用程序由兩 個線程組成,而這兩個線程都嘗試訪問同一個對象。本例中,該對象就是一個名為 JLAsink 的類,該類 包含兩個同步的方法,一個用於設置數據塊,一個用於檢索該數據塊。這兩個線程同時開始並且都在一個 循環中運行以同時訪問 JLAsink。一個線程稱為 setter 方法,另一個線程稱為 retrieval 方法。

圖 3 顯示在性能較差的示例應用程序中運行 JLA 的結果:

圖 3. 最初的 JLA 快照

可以從此屏幕截圖中看到,JLAsink 監視程序進行了 9,161 次 get,並且請求線程被阻塞,阻止它獲 得 25% 的鎖時間。很明顯,當處理嘗試獲得鎖的線程時,應用程序的這部分性能將有所下降。

圖 4 顯示在更高效的示例應用程序中運行的 JLA:

圖 4. 在優化的應用程序中運行 JLA 的快照

您可以看出 JLAsink 監視程序進行了 9,370 次 get,並且沒有阻塞任何一個線程。這表明在處理鎖 爭用時,該監視程序運行得比較理想。現在優化的代碼比未優化的代碼運行速度更快,您可以通過比較每 次運行的時間間隔看到這一點。 第二次運行訪問 JLAsink 對象的次數比第一次運行多,並且它花的時間 較少。

未來計劃

隨著當前功能的完善,該工具的發展正逐漸穩定。將來,我們的團隊將在 JLA 的基礎上發布一個新工 具,該工具將超越鎖統計信息,提供對活動 Java 應用程序的分析。該工具不僅僅具有 JLA 的功能,而 且還具有 EVTK 和 Dump Analyzer 工具的功能。目前該工具還處於設計階段。

結束語

在本系列的下一篇文章中,您將回到在本系列的第 1 部分介紹的 Dump Analyzer 工具。 您將對該工 具的擴展性獲得更深入的了解,並且還將學習如何構建您自己的分析模塊。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved