運行分析會話
使用 Eclipse 和 TPTP 來運行并分析 “玩具工廠”。TPTP 可以顯示活動對象的數量、執行時間等等。要使用 Eclipse 和 TPTP:
1. 啟動 Agent Controller。
2. 進入 Agent Controller bin 目錄,然后運行 RAStart.sh:
% cd $JAVA_DIR/tptpd/bin
% ./RAStart.sh
3. 在 Eclipse 中,進入工作臺并通過點擊 File > New > Project 創建一個新的 Java 項目。從選項列表中選擇 Java Project,然后點擊 Next。
4. 在下一個窗口中,輸入 Toy Maker 作為 Project Name,然后點擊 Finish。標題為 “Toy Maker” 的新項目應該會出現在 Package Explorer 面板中。
5. 在這個項目中,在 example 包中創建一個稱為 SpaceShipToy 的 Java 類。點擊 File > New > Class。
6. 在彈出的窗口中,在 Package 域中輸入 example 并在 Name 域中輸入 SpaceShipToy。窗口中的其他設置保持不變。
7. 點擊 Finish,F在應該會看到新類的骨架。
8. 將清單 1 中的代碼復制到 Eclipse 類編輯器中,一定要留下 package example 聲明,但是要替換空的類定義。保存代碼以使修改持久化,這還會使 Eclipse 自動地重新編譯類的新版本。
9. 如果要運行這個應用程序,點擊 Run > Run...,雙擊 Java Application,選擇 SpaceShipToy,然后點擊 Run。要與這個應用程序進行交互,點擊 Windows > Show View...,然后選擇 Console。
10. 輸入 1(數字一)并按 Return。屏幕應該與圖 2 相似。
圖 2. 在 Eclipse 下運行的玩具工廠
對同一個應用程序進行分析
要對同一個應用程序進行分析:
1. 點擊 TPTP Profile,然后選擇 Profile...。
2. 展開 Java Application 以顯示 SpaceShipToy。注意,Profile 窗口與點擊 Run 時出現的 Run 窗口相似,但是多了一個稱為 Profile 的選項卡。
3. 點擊 Profile 在分析器下啟動這個應用程序。如果透視圖沒有自動切換,那么點擊 Window > Open Perspective > Other...,然后選擇 Profiling and Logging。
4. 當 Profiling and Logging 透視圖出現時,展開 Profiling Monitor 視圖的內容,然后選擇以 <monitoring> 開頭的行。在選擇這一行時,出現一個控制臺視圖。
5. 輸入 0、1、2 和 9。屏幕應該與圖 3 相似。
圖 3. Profiling and Logging 透視圖與正在運行的應用程序
6. 點擊 Memory Statistics 視圖,然后展開與 example 包相關聯的行。這個視圖應該與圖 4 相似。這里有 4 個對象實例:三個代表 “構建的” 玩具,一個代表未被引用的玩具。
圖 4. 在構建三個玩具對象和一個未被引用的玩具之后的內存消耗
Memory Statistics 視圖中的列記錄了實例和內存使用統計數據:
• Total Instances 反映一個類的實例總數。
• Live Instances 顯示有多少個實例仍然被引用,還沒有被垃圾收集器收集。
• Collected 統計垃圾收集器已經收集了多少個類實例。
• Total Size (bytes) 和 Active Size (bytes) 分別顯示所有實例使用的累積內存總量(一種高水位標志)和活動實例當前使用的內存量。
結束試運行
要結束這一次試運行,切換回控制臺視圖,然后再次按 0、1 和 2 數字鍵。點擊 Monitoring 視圖中的 trash can 圖標強迫實施垃圾收集。好的垃圾收集器會收集所有未被引用的對象。在任何時候,都可以通過點擊 Refresh 刷新當前透視圖中的所有視圖,見圖 5。
圖 5. Refresh 按鈕
尋找需要的數據
Profiling and Logging 透視圖提供了許多視圖,其中提供關于應用程序狀態的大量數據。要查看視圖列表,點擊 Window > Show View > Other...,然后展開 Profiling and Logging 下面的列表。這個列表應該與圖 6 相似。
圖 6. Profiling and Logging 視圖的列表
收集數據來填充視圖
根據您的目標和面對的問題,可以收集數據來填充所有這些視圖或者其中一個視圖。在前一節中,收集的惟一數據是內存統計數據,這些數據填充在 Memory Statistics 視圖中。Monitoring 視圖與圖 7 相似。
圖 7. Monitoring 視圖中的基本統計數據
最下面的展開的列表表明,當前的分析配置只包含內存使用情況的統計數據。我們來創建一個收集盡可能多信息的新的分析配置,這樣您就能夠看到分析和性能工具提供的所有度量:
1. 點擊 TPTP Profile 按鈕中的小箭頭,然后選擇 Profile...。
2. 在 Profile 窗口中,選擇 SpaceShipToy,然后點擊窗口底部左邊的 New。
3. 在最右邊面板的頂部,在 Name 域中輸入 Lots of Data ,然后點擊 Apply。
4. 點擊 Profiling 選項卡,然后點擊 Add...。
5. 在下一個窗口中,輸入 All 作為 Profile set name 并在 Description 域中輸入 All of the data that's available。點擊 Next。
6. 下一個面板讓您選擇要收集的數據。展開所有選擇,然后選中所有復選框,如圖 8 所示。
圖 8. 要選擇的度量
7. 點擊 Execution Time Analysis。
8. 選擇 Collect method CPU time information 復選框,然后選擇 Show execution flow graphical details 選項。再次點擊 Next。下一個窗口(見圖 9)允許過濾掉您不感興趣的類。
圖 9. 從分析中排除無關的類
9. 出于這個例子的目的,點擊面板頂部的 Add... 來添加一個新的過濾器集。將這個過濾器集命名為 No Monkey Business 并點擊 OK。
10. 點擊規則列表右邊的 Add... 在過濾器集中添加一個新規則。在 Class name 域中輸入 example.SpaceShipToy 并在 Method name 域中輸入 main(星號),選擇 EXCLUDE 作為 Rule(見圖 10),然后點擊 OK。
圖 10. 編輯過濾器規則
11. 在更大的窗口中,點擊 Apply。
12. 現在已經定義了要分析的應用程序和要收集的度量。點擊 Profile。
13. 在 Profiling and Logging 透視圖中,點擊 Memory Statistics 視圖。應該會看到,根據剛才創建的規則,沒有對方法 example.SpaceShipToy.main() 執行度量。
提示和技巧
TPTP 工具提供了豐富的特性,可以幫助您深入地了解應用程序。另外,因為 TPTP 與 Eclipse 的其余部分很好地集成在一起,您會發現許多方便之處。
為了幫助您,下面提供一些提示和技巧。
快速建立數據過濾器
啟動一個分析會話并打開 Execution Statistics 視圖。這個視圖顯示一個應用程序中的所有類和方法(至少是還沒有在過濾器集中過濾掉的那些)。在這個視圖中右擊,打開圖 11 所示的快捷菜單。
圖 11. 快捷菜單
點擊 Filter out...,選擇 Profiling,然后點擊 OK。在下一個窗口(見圖 12)中,輸入 Monkey Business 作為過濾器名并輸入 build 作為過濾器字符串,然后選擇 Filter by 下面的 Method name 選項。點擊 OK 并再次點擊 OK。
圖 12. Edit Filter 窗口
視圖應該會改為只顯示 example.SpaceShipToy$Monkey.build() 方法的統計數據。
要想恢復視圖,再次看到所有方法,可以點擊 Filter(見圖 13)并選擇 No filter。要想編輯任何過濾器,可以點擊同一個按鈕并選擇 Manage filters...。
圖 13. Filter 按鈕
跳到源代碼
仍然留在 Execution Statistics 視圖中。雙擊 SpaceShipToy$Booster 類。這時就會切換到 Java 透視圖并直接跳到內部類 Booster 的定義。內存分析視圖和 Eclipse 代碼編輯器之間的這種連接是非常有價值的特性。
高級的復雜過濾器
可以使用 Edit Filter 窗口的 Advanced 選項卡來構建任意復雜的過濾器。高級過濾器 是一系列規則,其中每個規則列出一個屬性、一個條件(比如 “equal”、“not equal” 和 “like”)和一個值。您想知道一個實例消耗了多少內存嗎?這可以用高級過濾器來表達。
組織和排序
大多數數據視圖可以按照包、類和方法對數據進行組織。通過點擊大多數數據視圖頂部的三個按鈕之一(見圖 14),可以快速地改變數據的組織方式。
圖 14. 用于組織數據的三個按鈕
從左到右,分別是按照包、類和方法進行組織的按鈕。
還可以通過點擊任何列標題,對所有數據進行排序。點擊列標題一次,就對這個列按照升序進行排序;再次點擊同一個列標題,就按照降序顯示數據。
使用 UML2 序列圖深入了解代碼
TPTP 提供了另一個對了解正在運行的應用程序有幫助的特性:UML2 序列圖。這個圖不但顯示類和方法之間的調用序列,還可以突出顯示熱點,也就是消耗了大部分應用程序執行時間的代碼部分。
在序列圖中查看代碼
要使用 UML2 序列圖查看代碼:
1. 退出正在分析的所有玩具工廠應用程序實例。
2. 點擊 TPTP Profiling 按鈕中的小箭頭。選擇 Profile...,選擇 SpaceShipToy,點擊 Profiling 選項,然后選擇 All。
3. 點擊 Apply(如果需要的話),然后點擊 Profile。
4. 當應用程序在 Profiling Monitor 視圖中啟動時,右擊剛啟動的進程并選擇 Open With... > UML2 Thread Interactions 來打開 UML2 class Interactions 視圖。因為這個應用程序剛剛啟動,所以這個圖只顯示了對 main() 的調用,如圖 15 所示。
圖 15. 只顯示 main() 調用的簡單 UML 圖
5. 切換到控制臺視圖并與應用程序進行交互,從而產生更多的方法調用。然后切換回 UML2 Trace Interactions 視圖。UML 圖應該已經增大了,可能與圖 16 相似。
圖 16. 示例應用程序的 UML2 視圖
6. 將鼠標指針放在左邊空白處中的紅色條上,就會顯示一個表示 CPU 時間消耗的刻度條(見圖 17)。
圖 17. CPU 消耗刻度條
7. 深紅色表示最大。在這個應用程序中,SpaceShipToy 類的構造過程顯然是瓶頸。
對對象引用進行編目
另一個對正在運行的應用程序進行分析的有用特性是 Object References 視圖,這個視圖顯示應用程序中每種對象的引用數量。如果您的 Java 代碼看起來消耗了過多的內存,那么收集并查看對象引用可以幫助您找到出問題的代碼。
使用 Object References 視圖
使用 Object References 視圖與使用其他 TPTP 視圖一樣容易:
1. 終止正在分析的所有進程。
2. 在 Profiling Monitor 中右擊并選擇 Unload Profiling Data。按照提示刪除到目前為止收集的所有數據。
3. 選擇以前監視的所有進程并按 Delete。出現提示窗口時,選擇 Do not delete contents,然后點擊 Yes。
4. 對玩具工廠應用程序啟動一個新的分析會話。切換到控制臺視圖,然后按 1 2 9 來創建兩個玩具和未被引用的第三個 “玩具”。
5. 通過在 Profiling Monitor 視圖中點擊 Collect object references,收集正在使用的對象(見圖 18)。
圖 18. Collect Object References 按鈕
6. 在 Eclipse 工具欄上,點擊 Open Object References(見圖 19)來打開 Object References 視圖。Object References 視圖列出應用程序中使用的每個對象和對應的引用數量。
圖 19. Object References 按鈕
7. 展開 SpaceShipToy。引用表應該與圖 20 相似。已經創建了三個玩具,所以這個表是準確的,因為每個玩具包含一個推進器、一個太空倉(其中有兩只猴子)和三級火箭。
圖 20. 示例應用程序在某一時刻的 Object References 視圖
對本地 Java 應用程序使用 TPTP
除了對通過 Eclipse 工作臺構建和啟動的 Java 應用程序進行分析之外,還可以分析本地計算機上已經在運行的 Java 應用程序(應用程序也可以在遠程計算機上,但是這里不討論分析遠程應用程序的過程)?梢酝ㄟ^ TPTP 附著 到進程上。附著之后,就可以使用前面學習過的所有工具來探索和觀察內存分配。
附著到本地 Java 應用程序
要附著到本地 Java 應用程序:
1. 退出和刪除 Profiling Monitor 視圖中所有正在運行的進程。
2. 打開一個命令窗口并確認 PATH 和 JAVA_HOME 環境變量指向 JRE。
3. 確保 LD_LIBRARY_PATH 包含 TPTP 庫。在測試系統上,這些變量如下所示(根據您的系統配置,路徑名和目錄名可能不一樣):
% printenv
.
PATH=/bin:/usr/bin:/usr/X11R6/bin:/home/mstreicher/java/jdk/bin
JAVA_HOME=/home/mstreicher/java/jdk
JAVA_DIR=/home/mstreicher/java
LD_LIBRARY_PATH=/home/mstreicher/java/tptpd/lib:
4. 確保 TPTP Agent Controller 正在運行。進入包含 Agent Controller 的目錄,然后停止并重新啟動這個守護進程:
% cd $JAVA_DIR/tptpd/bin
% ./RAStop.sh
RAServer stopped, pid = 3163
RAServer stopped, pid = 3164
.
RAServer stopped, pid = 18108
% ./RAStart.sh
Starting Agent Controller
RAServer started successfully
5. 將玩具工廠應用程序作為單獨的獨立 Java 應用程序運行:
o 進入包含示例應用程序的工作空間目錄,可能是 $HOME/workspace/Toy Maker。在這個目錄中,應該會看到一個稱為 example 的目錄,其中包含 SpaceShipToy.java 的代碼和相關聯的 .class 文件。
o 將當前工作目錄(.(點號))添加到 CLASSPATH:
% cd $HOME/workspace/Toy Maker
% ls -F
example
% export CLASSPATH=.:$CLASSPATH
6. 用 -XrunpiAgent:server=enabled 選項通過 TPTP Agent Controller 啟動應用程序。enabled 模式以普通方式啟動 Java 應用程序并在后臺運行控制器。(如果在附著到應用程序之前不想執行它,那么使用 controlled 模式。)
% java -XrunpiAgent:server=enabled example/SpaceShipToy
7. 返回到 Eclipse,然后點擊 TPTP Profile 按鈕中的小箭頭。選擇 Profile...。在左邊的列表中,雙擊 Attach - Java Process。
8. 在下一個窗口中,在 Name 域中輸入 Toys,然后選擇 localhost 作為主機。點擊 Apply。
9. 通過點擊 Agents 選項卡選擇一個代理,如圖 21 所示。
圖 21. 選擇要附著的代理
點擊顯示的代理(如果當前沒有在分析其他應用程序或進程,那么應該有一個代理),然后點擊 >。為了保存這一修改,再次點擊 Apply。
10. 通過點擊 Profiling 選項卡并選擇一個分析集,從而選擇要收集什么數據?梢赃x擇 All,就會采用前面創建的分析集。
11. 點擊 Apply,然后點擊 Profile。Eclipse 應該會切換到 Profiling and Logging 透視圖。
12. 在大多數系統上,這時會出現與圖 22 相似的窗口。
圖 22. Profiling 提示
這個警告是正常的,它提醒您盡管已經附著到了這個進程,但是必須手工啟動監視。為了啟動監視,右擊剛啟動的分析進程,然后選擇 Start monitoring。
13. 切換回命令窗口,與應用程序進行交互。再返回 Eclipse 查看正在運行的應用程序的分析數據。完成之后,點擊 Terminate Process 按鈕(見圖 23)。
圖 23. Terminate Process 按鈕
將在命令窗口中殺死進程:
% java -XrunpiAgent:server=enabled example/SpaceShipToy
.
Stage complete.
Start stage...
Stage complete.
Start stage...
Stage complete.
zsh: killed java -XrunpiAgent:server=enabled example/SpaceShipToy
%
結束語
本教程演示了如何通過分析代碼來調整和改進 Java 應用程序。通過使用 Eclipse TPTP,可以運行代碼并探測哪些代碼段浪費了內存并導致性能降低。TPTP 還提供了其他工具,可以從大型日志文件中提取信息,以及自動地獲取和分析測試結果。
TPTP 中的其他工具包括一個記錄-回放設施(可以測試在 Eclipse 下運行的應用程序的 GUI)和一個稱為 XRay 的特殊分析器(專門用于分析源自 Eclipse 平臺的應用程序)。
文章來源于領測軟件測試網 http://www.kjueaiud.com/