JProfiler入門教程-簡單的java程式效能調優
推薦文章:JProfiler 入門教程
一、安裝JProfiler
從http://www.ej-technologies.com/下載5.1.2並申請試用序列號
二、主要功能簡介
1.記憶體剖析 Memory profiler
JProfiler 的記憶體檢視部分可以提供動態的記憶體使用狀況更新檢視和顯示關於記憶體分配狀況資訊的檢視。所有的檢視都有幾個聚集層並且能夠顯示現有存在的物件和作為垃圾回收的物件。
所有物件 顯示類或在狀況統計和尺碼資訊堆上所有物件的包。你可以標記當前值並顯示差異值。 記錄物件 Record objects 顯示類或所有已記錄物件的包。你可以標記出當前值並且顯示差異值。 分配訪問樹 Allocation call tree 顯示一棵請求樹或者方法、類、包或對已選擇類有帶註釋的分配資訊的J2EE元件。 分配熱點 Allocation hot spots 顯示一個列表,包括方法、類、包或分配已選類的J2EE元件。你可以標註當前值並且顯示差異值。對於每個熱點都可以顯示它的跟蹤記錄樹。
2.堆遍歷 Heap walker
在JProfiler的堆遍歷器(Heap walker)中,你可以對堆的狀況進行快照並且可以通過選擇步驟下尋找感興趣的物件。堆遍歷器有五個檢視:
類 Classes
顯示所有類和它們的例項。
分配 Allocations
為所有記錄物件顯示分配樹和分配熱點。
索引 References
為單個物件和“顯示到垃圾回收根目錄的路徑”提供索引圖的顯示功能。還能提供合併輸入檢視和輸出檢視的功能。
資料 Data
為單個物件顯示例項和類資料。
時間 Time
顯示一個對已記錄物件的解決時間的柱狀圖。
3. CPU 剖析 CPU profiler
JProfiler 提供不同的方法來記錄訪問樹以優化效能和細節。執行緒或者執行緒組以及執行緒狀況可以被所有的檢視選擇。所有的檢視都可以聚集到方法、類、包或J2EE元件等不同層上。CPU檢視部分包括:
訪問樹 Call tree
顯示一個積累的自頂向下的樹,樹中包含所有在JVM中已記錄的訪問佇列。JDBC,JMS和JNDI服務請求都被註釋在請求樹中。請求樹可以根據Servlet和JSP對URL的不同需要進行拆分。
熱點 Hot spots
顯示消耗時間最多的方法的列表。對每個熱點都能夠顯示回溯樹。該熱點可以按照方法請求,JDBC,JMS和JNDI服務請求以及按照URL請求來進行計算。
訪問圖 Call graph
顯示一個從已選方法、類、包或J2EE元件開始的訪問佇列的圖。
4. 執行緒剖析 Thread profiler
對執行緒剖析,JProfiler提供以下檢視:
執行緒歷史 Thread history 顯示一個與執行緒活動和執行緒狀態在一起的活動時間表。 執行緒監控 Thread monitor 顯示一個列表,包括所有的活動執行緒以及它們目前的活動狀況。 死鎖探測圖表 Deadlock Detection 顯示一個包含了所有在JVM裡的死鎖圖表。 目前使用的監測器 Current monitor useage 顯示目前使用的監測器並且包括它們的關聯執行緒。 歷史檢測記錄 History usage history 顯示重大的等待事件和阻塞事件的歷史記錄。 監測使用狀態 Monitor usage statistics 顯示分組監測,執行緒和監測類的統計監測資料。
5.VM 遙感勘測技術 VM telemetry
觀察JVM的內部狀態,JProfiler提供了不同的遙感勘測檢視,如下所示:
堆 Heap
顯示一個堆的使用狀況和堆尺寸大小活動時間表。
記錄的物件 Recorded objects
顯示一張關於活動物件與陣列的圖表的活動時間表。
垃圾回收 Garbage collector
顯示一張關於垃圾回收活動的活動時間表。
類 Classes
顯示一個與已裝載類的圖表的活動時間表。
執行緒 Threads
顯示一個與動態執行緒圖表的活動時間表。
三、實戰
(一)任務目標
找出專案中記憶體增大的原因
(二)配置說明
作業系統:Windows2003
Web容器:Tomcat5.0.23
JDK版本:sun1.4.2
監控型別:本地
Jprofiler安裝路徑:D:/jprofiler5
Tomcat安裝路徑:D:/Tomcat5
(三) 測試專案
1. 新建WEB專案test
2. 建包cn.test
3. 在該包下建類檔案TestMain.Java 和 TestBean.java
package cn.test;
public class TestBean {
String name = "";
}
package cn.test;
import java.util.ArrayList;
publicclass TestMain {
publicstatic ArrayList list = new ArrayList(); //存放物件的容器
public static int counter = 0; //作統計用
}
4.建測試用的JSP檔案init1.jsp、init2.jsp
Init1.jsp(每次執行都建立1萬個TestBean物件)
<%@ page language="java" import="cn.test.*" pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>init</title>
</head>
<body><%
for(int i=0;i<10000;i++){
TestBean b = new TestBean();
TestMain.list.add(b);
}
%>
SIZE:<%=TestMain.list.size()%><br/>
counter:<%=TestMain.counter++%>
</body>
</html>
Init2.jsp和init1.jsp一模一樣即可(後面有用)。
(四) 配置測試用例
1. 點選d:/jprofiler5/bin/jprofiler.exe
2. 執行選單SessionàIntegration WizardsàNew ServerIntegration
選擇是本地測試還是遠端測試:
選擇tomcat執行的指令碼檔案:
選擇虛擬機器的型別:
選擇監控埠:
用預設的即可
選擇Web容器是否和Jprofiler一起執行:
預設即可
配置提示:
在“遠端控制”的時侯要仔細閱讀一下。
然後選擇立即起動,開始執行。
點選“OK”,我們可以看到另外一個小窗口出來了:
Jprofiler的視窗為:
這樣我們就可以進行監控了!
(五) 開始測試
1. 在IE位址列中輸入:http://localhost/test/init1.jsp,執行一次,我們可以在記憶體檢視中看到cn.test.TestBean物件被建立了10000次:
2.標記現在的狀態,然後再執行init1.jsp和,init2.jsp可以讓我們找到哪些類在呼叫後沒有被釋放(很重要!!!)
檢視哪些類被髮生了變化:
紅色的變成是發生變化的物件及其數量。
我剛才執行了4次init1.jsp和1次init2.jsp,正好產生了50000個TestBean物件,和圖示顯示的一樣。
3. 過一會後,按F4鍵進行垃圾回收。但回收完成後,這些物件依然存在,說明某些地方對這個類的引用沒有被釋放!
4. 找出是哪些地方使用了TestBean類,並且沒有釋放它們
在cn.test.TestBean物件上點選右鍵選擇“Take Heap Snapshot for Selection”,觀察它的heap
下一步:
點選“OK”:
在該類中點選右鍵,在出現的選單中選擇“Use Selected Objects”:
出現如下視窗:
選擇”Allocations”,點選“OK”,然後我們要的結果就出來了
圖中顯示呼叫此類的地方是init1.jsp和init2.jsp,並且各自佔用的比率都列出來了。
既然問題的所在找出來了,接下來就該去解決問題了!
(五)總結
其實,我們在測試記憶體佔用時還可以另外寫一個釋放記憶體的JSP檔案來配合測試,會更清楚一些:
Free.sjp
<%@ page language="java" import="java.util.*,cn.test.*" pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>init</title>
</head>
<body>
<%TestMain.list.clear(); %> collection OK!
</body>
</html>
在點選完init1.jsp或init2.jsp後,可以看到記憶體是TestBean物件的數量增加了,然後執行free.sjp,接著再執行F4進行垃圾回收,立刻可以看到TestBean物件被釋放掉了。