標籤:
Java™ Platform, Standard Edition 6 (Java SE) 專註於提升效能,提供的增強工具可以管理和監視應用程式以及診斷常見的問題。本文將介紹 Java SE 平台中監視和管理的基本知識,並提供 Java SE 6 中相關增強詳細資料。
Java SE 6 對效能進行了深入研究,使用增強工具管理和監視應用程式並且診斷常見問題。這些改進包括:
- 監視和管理 API 增強
- 正式支援增強圖形監視工具 JConsole
- 提供增強 JAVA 虛擬機器(JVM)測試載入器
本文介紹了 Java SE 平台的監視和管理基本知識,並詳細介紹了最新版本中的效能監控和管理增強。還介紹了 Java SE 6 平台提供的診斷和故障排除工具。
要從本文獲益,您應當非常熟悉較早 Java SE 版本中引入的監視和管理功能。更多背景資訊,請參閱 參考資料。
監視和管理 API
Java SE 5 中引入的 java.lang.management 包定義了 9 個 MBean,稱為平台 MBean 或 MXBean(請參閱 參考資料)。每個 MXBean 封裝了 JVM 的一個單獨的功能區。從 Java SE 5 開始,JVM 包含了一個內建的 MBean 伺服器,稱為平台 MBean 伺服器。MBeans 位於其中並由其管理。表 1 列出了 Java 平台中的 9 個 MXBeans:
表 1. 平台 MBean
| 管理介面 |
託管的資源 |
ClassLoadingMXBean |
類裝載器 |
CompilationMXBean |
編譯器 |
MemoryMXBean |
記憶體 |
ThreadMXBean |
線程 |
RuntimeMXBean |
運行時 |
OperatingSystemMXBean |
作業系統 |
GarbageCollectorMXBean |
垃圾收集器 |
MemoryManagerMXBean |
記憶體管理器 |
MemoryPoolMXBean |
記憶體池 |
任何應用程式都可獲得並使用 JVM 提供的平台 MBean,方法是獲得目標 bean 的執行個體並調用合適的方法。MXBean 可用來監視本地和遠程 JVM 的行為並獲得相關資訊。
平台 MBean 可提供對資訊的訪問,例如裝載的類的數量、JVM 正常已耗用時間、記憶體消耗量、正在啟動並執行線程的數量,以及線程競爭統計資訊。
您可以使用以下兩種方式之一監視和管理 JVM 資源:
- 直接存取
MXBean 介面
- 使用
MBeanServer 介面進行間接訪問
使用 MXBean 介面直接存取
您可以從一個靜態Factory 方法獲得一個 MXBean 執行個體,該方法可以使您直接存取本地啟動並執行 JVM 的 MXBean 介面。ManagementFactory 類提供靜態Factory 方法獲得 MXBean。清單 1 示範了如何使用該工廠獲得 RuntimeMXBean 並獲得其中一個標準屬性 VmVendor 的值:
清單 1. 直接存取 MXBean
RuntimeMXBean mxbean = ManagementFactory.getRuntimeMXBean();// Get the standard attribute "VmVendor"String vendor = mxbean.getVmVendor();
使用 MBeanServer 介面進行間接訪問
平台 MBeanServer 介面使用 MXBeanServerConnection,使您能夠串連到遠程 JVM 並訪問運行在這些平台上的 MXBean。您可以使用ManagementFactory 類的 getPlatformMBeanServer 方法訪問平台 MBean 伺服器。清單 2 示範了如何獲得運行在遠程 JVM 上的RuntimeMXBean 並獲得 VmVendor 屬性的值:
清單 2. 間接訪問 MXBean
MBeanServerConnection serverConn;try { //connect to a remote VM using JMX RMI JMXServiceURL url = new JMXServiceURL( "service:jmx:rmi:///jndi/rmi://<addr>"); JMXConnector jmxConnector = JMXConnectorFactory.connect(url); serverConn = jmxConnector.getMBeanServerConnection(); ObjectName objName = new ObjectName(ManagementFactory.RUNTIME_MXBEAN_NAME); // Get standard attribute "VmVendor" String vendor = (String) serverConn.getAttribute(objName, "VmVendor");} catch (...) { }
有關 MXBeans 和 java.lang.management API 的更詳細資料,請參閱 參考資料 。
Java SE 6 中的 API 增強
Java SE 5 引入了 java.util.concurrent.locks 包,它為鎖定和等待條件提供了一種架構。這種架構有別於 Java 的內建同步支援並允許更加靈活地使用鎖。
Java SE 6 為 java.lang.management 包的 java.util.concurrent.locks 添加了支援。這包括可提供鎖資訊的新類以及對ThreadInfo、ThreadMXBean 和 OperatingSystemMXBean 介面的增強。
Java SE 6 引入了兩個新類:
LockInfo 包含有關鎖的資訊。
MonitorInfo 擴充了 LockInfo 並包含有關對象監視鎖的資訊。
ThreadInfo 類利用了這些新的對象以及引入的三種新方法:
getLockInfo() 返回 LockInfo 對象,給定線程將被阻塞以等待該對象。
getLockedMonitors() 返回當前被給定線程鎖定的 MonitorInfo 對象。
getLockedSynchronizers() 返回 LockInfo 對象,提供當前由給定線程鎖定的可擁有的同步程式。
在 Java SE 5 中,ThreadMXBean.getThreadInfo 方法只報告線程正在等待擷取的對象監視器或是被阻塞的監視器。Java SE 6 對這些方法進行了增強,從而可以報告線程正在等待擷取的 AbstractOwnableSynchronizer。
4 個新的方法被添加到 ThreadMXBean 介面中:
isObjectMonitorUsageSupported() 將測試虛擬機器是否支援對對象監視器的使用方式進行監視。
isSynchronizerUsageSupported() 測試虛擬機器是否對可擁有的同步程式使用方式進行監視。
findDeadlockedThreads() 返回處於死結狀態的線程的 ID 數組。死結線程被阻塞,防止進入對象監視器或同步程式。
dumpAllThreads() 為所有活動線程返回堆疊追蹤和同步資訊。
最後,OperatingSystemMXBean 介面將進行更新,以包括 getSystemLoadAverage() 方法,它可以返回前一分鐘的系統負載平均值。
除了提供編程支援以外,Java SE 6 還包括了一些診斷和故障排除工具,可用來檢測問題並監視 JVM 資源使用方式。接下來兩節將介紹並示範其中幾個可用的診斷工具。
Java 監視和管理主控台(JConsole)
Java SE 6 提供了對 JConsole 的正式支援,這是 Java 5 SE 中引入的監視和管理主控台。JConsole 使您能夠在運行時監視各種 JVM 資源統計資訊。這種特性特別適用於檢測死結、鎖競爭、記憶體流失和迴圈線程。它可以串連到一個本地或遠程 JVM 並可用來進行監視:
- 線程狀態(包括相關的鎖)
- 記憶體使用量情況
- 垃圾收集
- 運行時資訊
- JVM 資訊
以下小節將介紹 Java SE 6 對 JConsole 做出的增強。有關如何啟動和使用 JConsole 的更多資訊,請參閱 參考資料。
Attach API 支援
從 Java SE 6 開始,JConsole 實現了新的 Attach API。該 API 由兩個包組成 —com.sun.tools.attach 和 com.sun.tools.attach.spi— 可將應用程式的實現過程動態串連到目標虛擬機器並在 JVM 內運行代理。
過去,對於要使用 JConsole 進行監視的應用程式,要求使用 -Dcom.sun.management.jmxremote 選項啟動;現在,應用程式不再需要使用這個選項啟動。對動態串連的支援使 JConsole 能夠監視任何支援 Attach API 的應用程式。JConsole 在啟動時將自動檢測相容的應用程式。
增強 UI 和 MBean 表示
Java SE 6 對 JConsole 進行了更新,使它具有類似於 Windows® 作業系統或 GNOME 案頭的感觀(取決於所啟動並執行平台)。後文中顯示的螢幕使用的是 Windows XP 並展示了與之前版本不同的 UI 特性。
一旦啟動並與應用程式相關聯,將顯示由 6 個索引標籤群組成的 JConsole 視圖。每個選項卡表示一個不同的 JVM 資源或一組資源:
- Overview
- Memory
- Threads
- Classes
- VM Summary
- MBeans
Overview 選項卡以圖形的格式顯示有關記憶體使用量、線程、類和 CPU 使用方式的資訊。Overview 選項卡在一個頁面中顯示了一組相關資訊,而在以前需要在多個選項卡之間進行切換才能顯示。圖 1 展示了一個應用程式範例的 Overview 選項卡:
圖 1. JConsole Overview 選項卡
點擊查看大圖
Overview 選項卡顯示了 4 個反映 VM 資源使用方式的圖形以及一個挑選列表,可以修改顯示結果的時間範圍。第一幅映像 Heap Memory Usage 顯示堆記憶體量,隨時間流逝以 GB 的單位增加。該圖有助於檢測記憶體流失。如果您的應用程式出現了記憶體流失,堆記憶體使用量量將隨時間穩步增長。
Threads 圖形隨時間的增長描繪活動線程的數量,而 Classes 圖形描繪所裝載的類的數量。CPU Usage 圖表描述應用程式在其生命週期的不同時間點的 CPU 使用百分比。
圖 2 顯示的 VM Summary 選項卡是對 Java SE 6 版本的另一個新的增強。它提供了有關 JVM 的詳細資料,包括總的已耗用時間、線程資訊、裝載的類、記憶體統計資訊、垃圾收集和作業系統資訊。
圖 2. JConsole VM Summary 選項卡
點擊查看大圖
MBeans 選項卡進行了增強,可以更輕鬆地訪問 MBean 的操作和屬性。它顯示所有註冊到平台中的 MBean 的資訊,通過該選項卡可以訪問所有平台 MBeans。左側的樹結構顯示當前啟動並執行所有 MBean。當選擇一個 MBean 時,其 MBeanInfo 和描述符將顯示在右側的表中, 3 所示:
圖 3. JConsole MBean 選項卡
選擇 Attributes 節點將顯示 MBean 的所有屬性, 4 所示的 Threading MBean:
圖 4. MBean 屬性
注意,方框右側的屬性及其值對應於通過前文介紹的 java.lang.management 包的 ThreadMXBean API 獲得的屬性值,通過雙擊屬性值可獲得所列屬性的其他資訊,只有粗體顯示的屬性值可被展開。例如,雙擊 AllThreadIds 值將顯示 22 個線程的線程 ID, 5 所示:
圖 5. 展開的屬性值
可寫的屬性以藍色顯示並可以通過單擊它們進行編輯並輸入新值。例如,圖 5 所示的 ThreadContentionMonitoringAvailable 屬性就可以以這種方式在 JConsole 視圖中進行編輯。
選擇左側樹結構中的 Operations 節點將顯示與該 MBean 有關的操作。MBean 操作以按鈕的形式顯示在右側的地區中,並且當單擊時將調用指定的方法。圖 6 顯示了可用於 ThreadMXBean 的操作:
圖 6. MBean 操作HotSpot Diagnostic MBean
在 Java SE 6 中,JConsole 提供了對 HotSpot Diagnostic MBean 的支援。這個引入的 MBean 允許您執行 on-the-spot 診斷操作。其 API 允許使用者在運行時執行堆轉儲並設定其他 VM 選項。您可以從 MBean 選項卡訪問 HotSpot Diagnostic MBean,方法為展開 com.sun.management 節點並選擇 HotSpotDiagnostic。圖 7 顯示了可用於 HotSpot Diagnostic MBean 的方法:
圖 7. HotSpot Diagnostic MBeanJConsole 外掛程式支援
從 Java SE 6 開始,JConsole 提供了外掛程式支援,允許您構建自己的外掛程式來和 JConsole 一起運行。例如,您可以向 JConsole 主視圖添加一個自訂選項卡,用於訪問特定於應用程式的 MBeans 並執行自己的監視活動。
您必須擴充抽象的 com.sun.tools.jconsole.JConsolePlugin 類,建立一個自訂的 JConsole 外掛程式。您將為外掛程式實現 2 個方法,使之正確顯示在 JConsole 視圖中:
newSwingWorker() 返回 SwingWorker 對象,它將對外掛程式執行 GUI 更新。
getTabs() 返回被添加到 JConsole 視窗中的選項卡圖。
JConsole 使用其服務提供者機制檢測並裝載所有外掛程式類。因此,您必須為包含 META-INF/services/com.sun.tools.jconsole.JConsolePlugin 檔案的 JAR 檔案提供外掛程式類。該檔案應當包含一組完全符合規則的外掛程式類名,其中每行顯示一個類名。要將新外掛程式裝載到 JConsole 視圖,使用以下命令在命令列中運行 JConsole:
jconsole -pluginpath plugin_path
命令中的 plugin_path 指目錄路徑或者 JConsole 外掛程式的歸檔。您可以指定多條路徑。
Java SE 6 附帶了一個樣本 JConsole 外掛程式,稱為 JTop。JTop 將顯示當前應用程式內運行線程的 CPU 使用方式。要運行 JConsole 和 JTop,執行下面的命令:
jconsole -pluginpath JAVA_HOME/demo/management/JTop/JTop.jar
圖 8 展示了 JConsole 的一個執行個體,它選擇了 JTop 選項卡。左列顯示了所有運行線程的名稱。對於每個線程,將顯示它的 CPU 使用方式和線程狀態。當統計資訊發生變化時,視圖將自動重新整理。JTop 外掛程式可用於通過高 CPU 使用量識別線程。
圖 8. JConsole JTop 外掛程式監視和故障排除工具
除 JConsole 外,Java SE 6 還提供了對其他命令列工具的支援。這些診斷工具可以串連到任何應用程式而不要求應用程式以特殊模式啟動。它們使您能夠獲得更多應用程式資訊,從而確定它是否按預期運行。注意,列出的這些工具仍處於實驗性質,未來的 Java SE 版本未必能夠提供完全的支援。
監視工具
Java SE 6 包括了三個命令列工具,如表 2 所示,這些工具可用於監視 JVM 效能統計資訊:
表 2. 監視工具
| 工具 |
說明 |
jps |
JVM 進程狀態工具 |
jstat |
JVM 統計資訊監視工具 |
jstatd |
JVM jstat 精靈 |
jps 工具為目標系統的目前使用者列出虛擬機器。這對於使用 JNI Invocation API 而不是標準 Java 啟動程式啟動 VM 的環境特別有用。在這些環境中,通常很難從進程列表中識別 Java 進程。jps 工具解決了這個問題。
下面的例子示範了 jps 工具的使用。在命令列輸入 jps,該工具即可為具有存取權限的使用者列出虛擬機器和進程 ID,如清單 3 的樣本所示:
清單 3. 使用 jps 工具
$ jps16217 MyApplication16342 jps
jstat 工具使用 JVM 的內建測試載入器,提供有關效能和所運行應用程式的資源消耗資訊。該工具有助於診斷效能問題、與堆大小和垃圾收集有關的特殊問題。
jstatd 精靈是一個 Remote Method Invocation (RMI) 伺服器應用程式,它將監視 JVM 的建立和終止並提供介面以允許遠程監視工具串連到運行在本地主機的 JVM。例如,這個精靈允許 jps 工具列出遠程系統中的進程。
有關這些工具的更多文檔和使用樣本,請參閱 參考資料。
故障排除工具
Java SE 6 還提供了一些故障排除工具,如表 3 所示,這些工具可協助您找出應用程式中運行異常的部分:
表 3. 故障排除工具
| 工具 |
說明 |
jinfo |
配置資訊 |
jhat |
堆轉儲瀏覽器 |
jmap |
記憶體映射 |
jsadebugd |
服務能力代理偵錯工具 |
jstack |
堆疊追蹤 |
jinfo 命令列工具從運行中的 Java 進程或崩潰轉儲(crash dump)中擷取配置資訊,並對系統屬性和用於啟動虛擬機器的標記進行列印。
jhat 工具提供了一種方便的方法,可以在堆快照中瀏覽對象結構。Java SE 6 版本中引入的這個工具可以取代 Heap Analysis Tool (HAT),有助於檢測記憶體流失。
jmap 命令列工具為運行中的 VM 或核心檔案列印與記憶體有關的統計資訊。該工具還可以使用 jsadebugd 精靈查詢遠程機器中的進程或核心檔案。jmap 工具可檢測出是否過度使用了完成器,後者可導致出現 OutOfMemoryError 錯誤。
Serviceability Agent Debug Daemon (jsadebugd) 串連到一個 Java 進程或一個核心檔案,並充當一個調試伺服器。該工具當前只能用於 Solaris OS 和 Linux®。諸如 jstack、jmap 和 jinfo 這樣的遠程客戶機可以通過 Java RMI 串連到這種伺服器上。
jstack 命令列工具串連到指定的進程或核心檔案,並列印所有串連到虛擬機器的線程的堆疊追蹤資訊,包括 Java 線程和 VM 內部線程,有時也包括本地堆棧架構。該工具還執行死結檢測。它使用 jsadebugd 精靈查詢遠程機器上的進程或核心檔案。jstack 工具可用於檢測死結問題。
關於這些工具的更多文檔和使用樣本,請參考 參考資料。
結束語
Java 6 平台對 VM 測試、管理 API 和 JDK 工具提供了一些增強,可協助有效地確定和診斷 Java 應用程式中的效能和記憶體問題。本文介紹了對 Java SE 監視和管理架構添加的增強以及為開發人員提供的診斷命令列工具。
Java 應用程式的平均效能隨時間穩步提高。現在,使用 Java SE 6 版本,Java 效能可與 C 或 C++ 相媲美。在很多情況下,Java 代碼的運行速度顯著提升。您還可以使用本文介紹的工具實現更好的效能最佳化。請您親自嘗試。我們可以確保幫您找到以前從未進行過的應用程式最佳化。
在 Java SE 6 中監視和診斷效能問題