程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java技術,IBM風格: 監視和判斷問題

Java技術,IBM風格: 監視和判斷問題

編輯:關於JAVA

隨著時間的推移,IBM 為它的 Java 運行時實現開發了許多監視和問題診斷設施。利用這些工具,IBM 支持團隊、Java 應用程序開發人員和生產操作人員可以診斷和解決在 Java 開發中遇到的問題。

本文討論三種主要的設施,因為它們是在 Java 技術的 IBM 實現的最新版本中實現的:跟蹤引擎、轉儲引擎和 DTFJ 工具 API。它們都有助於 Java 開發人員判斷問題的根源。

跟蹤引擎

在判斷軟件的問題時,跟蹤信息是一種強大的工具:可以使用它有效地研究問題場景(比如功能性錯誤、競爭狀態和性能問題),而且它非常有助於了解程序的流程。

IBM 在 SDK 1.2.2 中首次在它的 Java 運行時實現中引入了跟蹤引擎,幫助 IBM 開發團隊診斷 Java 虛擬機(JVM)的缺陷。這種跟蹤設施的目的是為虛擬機本身提供一個低開銷、高性能、可配置的跟蹤機制。在後續的版本中,進行了顯著的調整和改進;IBM SDK 的當前版本提供一個高性能的引擎,它能夠捕捉 JVM、Java Class Libraries(JCL)和部署到運行時中的任何 Java 應用程序代碼的跟蹤數據,而不需要任何其他設施。

激活和控制跟蹤

可以通過多種機制激活和控制跟蹤引擎:

通過命令行選項 -Xtrace

使用跟蹤屬性文件

通過 com.ibm.jvm.Trace API,使用 Java 代碼進行動態控制

使用跟蹤觸發器事件

從外部代理使用基於 C 的 JVM RAS Interface(JVMRI)

控制跟蹤的主要方法是使用命令行選項 -Xtrace,或者在選項集比較長或復雜的情況下,使用可選的跟蹤屬性文件。

-Xtrace 選項由一系列標志或標志-值對組成,這些設置用來決定跟蹤應該寫到 stderr、內部緩沖區還是二進制文件;是啟用方法跟蹤、JVM 跟蹤,還是兩者都啟用;應該跟蹤哪些跟蹤點;是跟蹤對跟蹤點的任何修改,還是在發生事件時觸發轉儲。

激活跟蹤的基本知識

在使用 IBM 的跟蹤設施時,需要決定的第一件事是應該將跟蹤輸出定向到哪個目的地。表 1 簡要描述這些目的地以及將多少跟蹤點數據發送給它。例如,print 將所有跟蹤數據定向到 stderr,minimal 將每個跟蹤點的數據子集定向到內存緩沖區,然後又可以使用 output 選項將這些緩沖區中的數據捕捉到文件中。

表 1. 跟蹤目的地

關鍵字 功能 minimal 將選擇的跟蹤點(只有標識符和時間戳)定向到核心緩沖區。不記錄相關聯的跟蹤數據。 maximal 將選擇的跟蹤點(標識符和時間戳以及相關聯的數據)定向到核心緩沖區。 count 統計在 JVM 的生命期內調用選擇的跟蹤點的次數。 print 將選擇的跟蹤點定向到 stderr,不進行縮進。 iprint 將選擇的跟蹤點定向到 stderr,進行縮進。 external 將選擇的跟蹤點定向到 JVMRI 監聽器。 exception 將選擇的跟蹤點定向到為異常保留的核心緩沖區。

應該將每個關鍵字的值設置為所需的跟蹤點。例如:

-Xtrace:maximal=all 將來自所有 JVM 跟蹤點的所有信息記錄到內部回繞緩沖區中。

-Xtrace:iprint=awt 將所有 JVM 內部 AWT 跟蹤點記錄到 stderr,在進入和退出時進行縮進。

-Xtrace:iprint=mt 激活方法跟蹤並將輸出發送到 stderr,進行縮進。

僅僅使用表 1 中的選項並不會生成任何輸出;必須單獨提供要跟蹤的方法名。注意,IBM Diagnostics Guide 的第 32 章 “Tracing Java applications and the JVM” 詳細討論了所有跟蹤選項。

將跟蹤數據放進內部緩沖區中

使用存儲內緩沖區進行跟蹤是非常高效的,因為在探測到問題或者使用 API 將緩沖區寫入文件之前,不執行顯式的 I/O。緩沖區被分配給每個線程,這防止線程之間發生沖突並防止各個線程的跟蹤數據相互干擾。例如,如果某個線程沒有被調度,當轉儲緩沖區時它的跟蹤信息仍然是可用的。

要查看跟蹤數據,必須轉儲緩沖區並進行格式化。當發生以下情況時,自動進行緩沖區的轉儲:

發生未被捕捉的 Java 異常

發生操作系統信號或異常

調用 com.ibm.jvm.Trace.snap() Java API

調用 JVMRI TraceSnap 函數

將跟蹤數據放進文件中

可以連續地將跟蹤數據寫到文件中,作為存儲內跟蹤的擴展;但是在這種情況下不是為每個線程分配一個緩沖區,而是至少分配兩個。當一個跟蹤緩沖區滿了時,將它寫到文件系統中,這使線程能夠連續運行。根據跟蹤量、緩沖區大小和輸出設備的帶寬,可以將多個緩沖區分配給給定的線程,從而與生成跟蹤數據的速度相匹配。

要將 minimal 或 maximal 跟蹤選項的輸出寫到文件中,應該使用 output 關鍵字,對於 exception 選項使用 exception.output 關鍵字:

-Xtrace:maximal=all,output=trace.out 將跟蹤數據寫到文件 trace.out 中。

-Xtrace:maximal=all,output={trace.out,5m} 將跟蹤數據寫到文件 trace.out 中,當文件達到 5MB 時進行回繞。

-Xtrace:maximal=all,output={trace#.out,5m,5} 將跟蹤數據依次寫到 5 個文件中,每個文件 5MB,# 用文件的序號代替。在這個示例中,創建文件 trace0.out 到 trace4.out,每個文件包含最近的 5MB 跟蹤數據。當 5 個文件都填滿時,JVM 依次覆蓋 trace0.out 到 trace4.out。這個選項可以創建的最大文件數是 36 個,# 字符被替換為 0 到 9,然後是 A 到 Z。

還可以在文件名中進行以下替換:

%p:Java 進程的 ID。

%d:yyyymmdd 格式的當前日期。

%t:hhmmss 格式的當前時間。

對跟蹤文件進行格式化

跟蹤格式化器(trace formatter) 是一個可以在任何平台上運行的 Java 程序,可以對來自任何平台的跟蹤文件進行格式化。IBM SDK 在 core.jar 中提供了這個格式化器,它還需要一個稱為 TraceFormat.dat 的文件,其中包含格式化模板。這個文件在 jre/lib 中。可以用以下命令行啟動跟蹤格式化器:

java com.ibm.jvm.format.TraceFormat input_file [output_file]

在這裡,com.ibm.jvm.format.TraceFormat 是跟蹤格式化器類,input_file 是要進行格式化的二進制跟蹤文件的名稱,output_file 是可選的輸出文件名。如果沒有指定輸出文件,那麼默認的輸出文件名是輸入文件名加上 .fmt。

動態記錄器

IBM VM 跟蹤設施包含一個動態記錄器(flight recorder),它連續地將來自關鍵跟蹤點子集的數據捕捉到內存緩沖區中。當出現運行時問題時捕捉這些緩沖區,可以用來診斷問題並分析 VM 的歷史。VM 初始化過程用一小組跟蹤點啟動跟蹤,這些跟蹤點被捕捉到回繞式存儲內緩沖區中。可以使用這些信息初步診斷 Java 運行時中的任何問題,並確保 -verbose:gc 選項提供的數據子集總是可用的。垃圾收集數據也出現在 Java 轉儲文件中。

內部的動態記錄器使用一個命令行選項:

-Xtrace:maximal=all{level1},exception=j9mm{gclogger}

如果在命令行上指定 -Xtrace,或者在屬性文件中設置它,那麼清除激活的跟蹤點集。

方法跟蹤

可以利用 Java 方法跟蹤來跟蹤每個線程對方法的調用,包括進入方法和退出方法,這種跟蹤針對 Java 運行時的 IBM 實現上運行的任何代碼進行。這不需要對 Java 代碼進行任何手工處理,可以使用它跟蹤 JCL、第三方包或應用程序代碼。

方法跟蹤功能尤其適合調試發生競爭狀態和在方法之間傳遞了不合適的參數而導致異常的情況。由於跟蹤時間戳具有毫秒級的精度,方法跟蹤還可以用來調試性能問題。

在命令行上調用方法跟蹤的辦法是,添加 methods 關鍵字標志並將 mt 設置給目的地關鍵字之一(maximal、minimal、print)。methods 關鍵字允許按照類、方法名或這兩者選擇要跟蹤的方法。可以使用通配符和取反操作符 ! 建立復雜的選擇條件。例如:

-Xtrace:print=mt,methods={*.*,!java/lang/*.*}:對於除了 java.lang 包中的方法和類之外的所有方法和類,將方法跟蹤寫到 stderr 中。

-Xtrace:maximal=mt,output=trace.out,methods={tests/mytest/*.*}:對於 tests.mytest 包中的所有方法,將方法跟蹤寫到文件中。(注意,這個選項只選擇要跟蹤的方法。)

在發生跟蹤事件時觸發

IBM 跟蹤引擎最強大的特性之一是它能夠在發生跟蹤事件時觸發,這有助於創建目的明確的跟蹤輸出並減少產生的跟蹤數據量。這會提高被調試的應用程序的性能(由於開銷大大降低了)和解釋數據的速度(由於多余的數據減少了)。

跟蹤引擎能夠在任何給定的跟蹤點上觸發,包括 VM 內部的跟蹤點或 Java 方法,而且在發生事件時可以執行許多操作,見表 2:

表 2. 跟蹤引擎操作

關鍵字 功能 suspend 暫停所有 跟蹤(特殊跟蹤點除外)。 resume 恢復所有 跟蹤(由 resumecount 屬性和 Trace.suspendThis() 調用暫停的線程除外)。 suspendthis 增加這個線程的暫停計數。非零的暫停計數會停止這個線程的所有跟蹤。 resumethis 減少這個線程的暫停計數(如果這個值大於零的話)。如果暫停計數到達零,那麼這個線程的跟蹤就會恢復。 sysdump 生成非破壞性的系統轉儲。 javadump 生成 Java 轉儲。 heapdump 生成堆轉儲。 snap 將所有激活的跟蹤緩沖區寫到當前工作目錄中的一個文件中。

可以使用 trigger 命令行關鍵字激活觸發跟蹤,這個關鍵字決定在發生事件時執行表 2 中的哪些操作。注意,觸發選項控制其他跟蹤屬性已經選擇的跟蹤數據是正常生成,還是被阻塞。

使用以下格式指定方法事件上的觸發:

-Xtrace:trigger=method{method spec, entry action, exit action, delay count, match count}

當進入與 method spec 匹配的任何方法時,執行 entry action。當退出方法時,執行 exit action。如果指定了 delay count,那麼只有當進入和退出的次數大於 delay count 時才執行 entry action 和 exit action。如果指定了 match count,那麼操作的執行次數不超過這個值。請考慮以下示例:

-Xtrace:trigger=method{java/lang/StackOverflowError*, sysdump}

這在第一次(而且只在第一次)調用 StackOverflowError 方法時(進行調用的是 <clinit> 方法),創建一個非破壞性的系統轉儲。

可以使用 suspend 和 resume 選項並結合 resumecount 或 suspendcount 關鍵字來暫停和恢復單獨的線程或所有線程:

-Xtrace:resumecount=1 
-Xtrace:trigger=method{HelloWorld.main,resume,suspend}

這些選項在調用 HelloWorld.main() 時開始跟蹤所有線程,在 HelloWorld.main() 返回時停止跟蹤。這實際上意味著在 Java 運行時啟動時不進行跟蹤,只在 HelloWorld 應用程序運行期間生成跟蹤數據。

用跟蹤引擎能夠實現什麼?

可以使用跟蹤引擎為 Java 運行時本身或其中運行的應用程序代碼中的任何問題生成數據流或歷史數據。這些歷史數據加上轉儲引擎生成的狀態數據能夠幫助開發人員了解和調試許多問題。

轉儲引擎

Java 運行時的 IBM 實現中內置了轉儲引擎,它能夠提供大多數必需的數據,幫助 IBM 支持團隊對 Java 運行時本身或 IBM SDK 提供的 JCL 中的問題進行診斷。轉儲引擎的默認設置在發生特定事件時觸發許多不同類型的轉儲,可以對這些轉儲進行後期處理來判斷許多問題的原因。

還可以使用許多轉儲和事件來診斷 Java 應用程序中的問題,因為用來診斷 JCL 中的問題的過程同樣可以用來診斷其他 Java 類中的問題。

轉儲類型

IBM 轉儲引擎可以生成 4 種類型的轉儲(在 z/OS® 上有 5 種),如果需要的話,還能夠在單獨的進程中執行一個工具。每個轉儲類型本身都是非破壞性的,但是如果是由故障事件(比如 SIGSEGV/GPF)造成的,就會變成破壞性的。表 3 描述可用的轉儲類型:

表 3. 轉儲類型

關鍵字 轉儲類型 說明 java Java 轉儲 包含環境、鎖、線程堆棧和類信息的狀態報告。 heap 堆轉儲 這種轉儲包含 Java 堆上每個 Object 的大小和引用細節。 snap Snap 轉儲 寫到文件中的跟蹤緩沖區內容。 system 系統轉儲 進程映像,采用操作系統的一般格式(核心文件、微轉儲或事務轉儲)。 ceedump CEEDUMP z/OS 特有的線程堆棧和寄存器匯總文件。 tool 工具代理 使用提供的命令行執行一個預定義的工具。

轉儲事件

IBM 轉儲引擎能夠在發生表 4 中的事件時生成任何或所有類型的轉儲:

表 4. 事件類型

事件 說明 gpf 發生未預料到的崩潰,比如 SIGSEGV 或 SIGILL。 user 發生 SIGQUIT 信號(Windows 上的 Control+Break,Linux 上的 Control+\,z/OS 上的 Control+V)。 vmstart VM 完成初始化。 vmstop VM 將要關閉。 load 裝載了一個新類。 unload 卸載了一個類裝載器。 throw 拋出了一個 Java 異常。 catch 捕捉到了一個 Java 異常。 uncaught 有一個 Java 異常未被應用程序處理。 thrstart 啟動了一個新線程。 thrstop 停止了一個現有線程。 blocked 一個線程被阻塞,進入監視器。 fullgc 啟動垃圾收集。

這些事件本身為指定何時生成每種轉儲提供了很大的靈活性,但是如果結合使用轉儲過濾器 的話,靈活性還會大大提高。可以在每種事件上添加一個過濾器,從而以更細的粒度控制何時創建轉儲。例如,可以在 throw、catch 和 uncaught 事件上添加異常名或錯誤名。

設置轉儲選項並修改默認設置

使用 -Xdump 命令行選項和一系列標志來設置各種轉儲選項。可以使用 -Xdump:what 查看默認的轉儲選項,見清單 1:

清單 1. -Xdump:what 輸出

C:\home> java -Xdump:what

Registered dump agents
----------------------
dumpFn=doSystemDump               // Generate a system dump 
events=gpf+abort                // on SIGSEGV and SIGABRT events
filter=
label=C:\home\core.%Y%m%d.%H%M%S.%pid.dmp    // location and name of file
range=1..0                   // write on every event occurrence
priority=999                  // write this dump first
request=serial                 // write in serial
opts=
----------------------
dumpFn=doSnapDump                // Generate trace snap file
events=gpf+abort                // on SIGSEGV and SIGABRT events
filter=
label=C:\home\Snap%seq.%Y%m%d.%H%M%S.%pid.trc  // location and name of file
range=1..0                   // write on every event occurrence
priority=500                  // write after higher priority dumps
request=serial                 // write in serial
opts=
----------------------
dumpFn=doSnapDump                // Generate trace snap file
events=uncaught                 // on uncaught exceptions
filter=java/lang/OutOfMemoryError        // that match OutOfMemoryError
label=C:\home\Snap%seq.%Y%m%d.%H%M%S.%pid.trc  // location and name of file
range=1..4                   // write only on the first four events
priority=500                  // write after higher priority dumps
request=serial                 // write in serial
opts=
----------------------
dumpFn=doHeapDump                // Generate heap dump file
events=uncaught                 // on uncaught exceptions
filter=java/lang/OutOfMemoryError        // that match OutOfMemoryError
label=C:\home\heapdump.%Y%m%d.%H%M%S.%pid.phd  // location and name of file
range=1..4                   // write only on the first four events
priority=40                   // write after higher priority dumps
request=exclusive+prepwalk           // make sure the heap is walkable
opts=PHD                    // write in "PHD" format
----------------------
dumpFn=doJavaDump                // Generate java dump file
events=gpf+user+abort              // on SIGSEGV, SIGABRT and SIGQUIT events
filter=
label=C:\home\javacore.%Y%m%d.%H%M%S.%pid.txt  // location and name of file
range=1..0                   // write on every event occurrence
priority=10                   // write after higher priority dumps
request=exclusive                // obtain exclusive access to walk the VM
opts=
----------------------
dumpFn=doJavaDump                // Generate java dump file
events=uncaught                 // on uncaught exceptions
filter=java/lang/OutOfMemoryError        // that match OutOfMemoryError
label=C:\home\javacore.%Y%m%d.%H%M%S.%pid.txt  // location and name of file
range=1..4                   // write only on the first four events
priority=10                   // write after higher priority dumps
request=exclusive                // obtain exclusive access to walk the VM 
opts=
---------------------- 

可以通過修改語法來添加其他轉儲。要在發生未捕捉的套接字異常時生成 Java 轉儲,使用以下語法:

-Xdump:java:events=uncaught,filter=java/net/SocketException

要刪除所有堆轉儲,使用以下語法:

-Xdump:heap:none

使用轉儲引擎能夠實現什麼?

可以使用轉儲引擎的功能解決 IBM SDK 本身中的問題;更重要的是,可以利用它們解決 Java 應用程序中的問題。在發生 OutOfMemoryErrors 時能夠生成 Java 轉儲文件和堆轉儲,因此能夠診斷內存洩漏並分析任何大對象的堆棧。能夠在發生其他異常時生成 Java 轉儲文件,因此能夠使用轉儲中的線程堆棧數據來調試潛在的競爭狀態。

另外,在發生各種事件時能夠創建非破壞性的系統轉儲,這意味著可以使用 DTFJ API 研究在發生事件時 Java 應用程序的任何部分的狀態。

Diagnostic Toolkit and Framework for Java

DTFJ API 是一個基於 Java 的 API,工具的編寫者可以使用它訪問關於 Java 進程的信息,這只需要有進程映像的快照(例如,系統轉儲),工具的編寫者不需要了解各種系統轉儲格式以及 Java 對象和其他 Java 結構在內存中的布局方式。

正如前面提到的,Java 運行時的 IBM 實現能夠使用跟蹤或轉儲引擎創建非破壞性的系統轉儲。另外,還可以使用 com.ibm.jvm.Dump.SystemDump() 靜態方法創建非破壞性的系統轉儲。還可以使用操作系統工具獲得同樣的結果,例如 AIX® 上的 gencore 或 Linux 上的 gcore。

創建非破壞性的系統轉儲使工具能夠使用 DTFJ API 從正在運行的系統獲得信息,還可以對發生故障和已經關閉的系統進行分析。

體系結構

DTFJ API 是一個分層的接口,它獨立於運行時實現:這個 API 本身可以用於多種操作系統和硬件平台、多種虛擬機實現和多種語言。DTFJ API 中包含的基本擴展集針對的是 Java 運行時,因此使工具的編寫者能夠了解和探察 JVM 數據結構,Java 運行時的 IBM 實現附帶的 DTFJ 實現能夠提供關於這些運行時中的數據結構的信息。

這個 API 本身受到了 Reflection API 的深刻影響,並結合了 Java 進程的一個層次化視圖,這個視圖使用 Iterator 訪問從高層對象到更特定對象的各個對象。這提供了許多可用的數據對象,從進程的 Image 到單獨的 JavaField 和 JavaMethod 對象,可以探察這些對象來獲得在建立系統轉儲時它們包含的數據。圖 1 給出了 DTFJ API 可以了解和探察的一些數據對象:

圖 1. DTFJ 數據對象概述

運行 JExtract

因為各種操作系統生成不同的系統轉儲格式,而且隨著時間的推移內部 Java 運行時數據結構可能會發生一些必要的改變,所以需要對系統轉儲運行一個稱為 JExtract 的實用程序,然後才能使用 DTFJ API 訪問系統轉儲。這個操作需要由生成系統轉儲時運行的相同 Java 運行時版本來執行,而且應該在同一個系統上執行。

JExtract 實用程序了解系統轉儲和 Java 運行時內部數據結構的格式。它利用這一知識創建一個 XML 描述文件,這個文件為系統轉儲文件提供索引,指出各個數據結構的位置。然後,DTFJ 就可以結合使用系統轉儲和 JExtract 生成的 XML 文件來生成工具所請求的信息。

盡管 JExtract 是系統轉儲的後處理程序,但是可以使用轉儲引擎的 tool 選項在創建系統轉儲之後自動調用 JExtract。例如,為了在發生 OutOfMemoryErrors 時創建系統轉儲,使用以下語法:

-Xdump:tool:events=uncaught,filter=
 OutOfMemoryError,exec="jextract .\core.%Y%m%d.*.%pid.dmp"

可以使用 DTFJ API 實現什麼?

可以使用 DTFJ API 訪問系統轉儲中的大量信息。這包括關於運行進程的平台的信息:物理內存、CPU 數量和類型、庫、命令行、線程堆棧和寄存器。它還可以提供關於 Java 運行時和 Java 應用程序的狀態的信息,包括類裝載器、線程、監視器、堆、對象、Java 線程、方法、編譯的代碼和字段及其值。

因為提供的數據范圍非常廣泛,DTFJ API 為創建各種工具提供了很大的靈活性。例如,在比較簡單的層面上,它使工具能夠查明各個緩存的大小和內容,從而更有效地調整這些緩存所需要的 Java 堆內存量。

開始使用 DTFJ

創建基於 DTFJ 的工具的第一步是獲得與系統轉儲相關的 Image 對象,然後從 ImageAddressSpace 獲得 ImageProcess 對象,見清單 2:

清單 2. 使用 DTFJ 獲得當前進程

Image theImage = new ImageFactory().getImage(new File(fileName));
ImageAddressSpace currentAddressSpace =
 (ImageAddressSpace) theImage.getAddressSpaces().next();
ImageProcess currentProcess = currentAddressSpace.getCurrentProcess();

在大多數平台上,映像中只有一個 ImageAddressSpace 和 ImageProcess 對象;但是,大型機操作系統可能有多個實例。

獲得 ImageProcess 對象之後,就可以訪問本機線程,見清單 3:

清單 3. 獲得線程和堆棧幀

Iterator vmThreads = process.getThreads();
ImageThread vmThread = (ImageThread) vmThreads.next();
Iterator vmStackFrames = vmThread.getStackFrames();

還可以訪問各個 ImageModule(庫)對象,見清單 4:

清單 4. 獲得已經裝載的庫

Iterator loadedModules = process.getLibraries()

可以從 ImageProcess 對象獲得 JavaRuntime,見清單 5:

清單 5. 獲得 Java 運行時

JavaRuntime runtime = (JavaRuntime) process.getRuntimes().next();

這樣就可以訪問所有 Java 結構。

獲得了 JavaRuntime 對象之後,就可以編寫工具來探察正在運行的任何 Java 應用程序。清單 6 中的簡單示例演示了如何遍歷 Java 堆上的所有對象並統計每種類型的對象的數量:

清單 6. 統計轉儲中每種對象的數量

.. 
  Map<String,Long> objectCountMap = new HashMap<String,Long>();

  Iterator allHeaps = currentRuntime.getHeaps();

  /* Iterate over each of the Java heaps and call countObjects on them to */
  /* populate the object type count HashMap                */
  while(allHeaps.hasNext()) {
     countObjects((JavaHeap)allHeaps.next(),objectCountMap);
  }

  /* print out each of the entries in the HashMap of object types    */
  for (String objectClassName : objectCountMap.keySet()) {
     System.out.println(objectClassName +
      " occurs " + objectCountMap.get(objectClassName));
  }

  private static void countObjects(JavaHeap currentHeap,
   Map<String, Long> objectCountMap)
  throws Exception{

    /* Iterate over each of the Objects on the supplied Java heap    */
    Iterator currentHeapObjects = currentHeap.getObjects();
    while(currentHeapObjects.hasNext()) {
      JavaObject currentObject = (JavaObject)currentHeapObjects.next();

      /* Get the name of the class from the object          */
      String objectClassName = currentObject.getJavaClass().getName();
      long objectCount = 0;

      /* Add the class name to the HashMap, or increase the count if it */
      /* already exists                         */
      if (objectCountMap.containsKey(objectClassName)) {
         objectCount = objectCountMap.get(objectClassName);
      }
      objectCountMap.put(objectClassName, objectCount + 1);
    }
  }

結束語

本文討論的所有功能都可以幫助您診斷和解決在 Java 部署中遇到的開發和生產問題。結合使用這三種主要的設施來生成歷史跟蹤數據和詳細的狀態數據,再用簡單的 API 訪問狀態數據,就可以以強大且靈活的方式探察 Java 應用程序並解決問題。

本文結束了對 Java 虛擬機的 IBM 實現中主要改進和改變的討論。具體地說,我們討論了內存管理、類共享和應用程序監視,描述了如何利用這些功能改進 Java 應用程序的性能和可用性。關於這些改進和其他改進的更多信息可以在 IBM Diagnostics Guide 中找到,還可以通過 IBM Runtimes and SDKs 論壇進行反饋和討論。

在這個系列的最後一篇文章中,Java 安全開發團隊將討論 IBM 對 Java 平台的安全改進。那篇文章將介紹每個安全組件以及它們提供的功能。

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