1.jps :虛拟機程序狀況工具
-q 隻輸出LVMID,省略主類的名稱
-m 輸出虛拟機程序啟動時傳遞給主類main()函數的參數
-l 輸出主類全名,如果程序執行的是jar包,輸出jar路徑
-v 輸出虛拟機啟動時JVM參數
2.jstat:虛拟機統計資訊監視工具
參數: interval 查詢間隔 count 查詢次數
執行個體:
假設需要沒250毫秒查詢一次程序2764垃圾收集的狀況,一共查詢20次,指令為:
jstat -gc 2764 250 20
其他參數:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIwczX0xiRGZkRGZ0Xy9GbvNGL2EzXlpXazxSP9EVT3FEVlZnSXVGb01mY2JlMMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLycDN0UjMwkDMwEjMwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
3.jinfo : java配置資訊工具(實時檢視和調整虛拟機的各項參數。)
jinfo pid
4.jmap: java記憶體映像工具(用于生成堆轉儲快照)
jmap vmid
其他參數:
例子:生成一個正在運作的idea的dump快照檔案
jmap -dump:format=b,file=idea.bin 3500
5.jhat: 虛拟機堆轉儲快照分析工具
例子:
jhat idea.bin
分析結果顯示:
http://localhost:7000/
6.jstack: java 堆棧跟蹤工具(使用者生成虛拟機目前時刻的線程快照)
指令格式:
jstack [option] vmid
例子:
jstack -l 3500
項目中檢視堆棧資訊:
for (Map.Entry<Thread, StackTraceElement[]> threadEntry :
Thread.getAllStackTraces().entrySet()) {
Thread thread = threadEntry.getKey();
StackTraceElement[] stack = threadEntry.getValue();
if (thread.equals(Thread.currentThread())) {
continue;
}
out.print("\n線程:" + thread.getName() + "\n");
for (StackTraceElement element : stack) {
out.print("\t" + element + "\n");
}
}
7.JConsole:java監視與管理平台
JConsole 監視代碼
import java.util.ArrayList;
import java.util.List;
/**
* VM: -Xms100m -Xmx 100m -XX:+UseSerialGC
*/
public class TestJconsole {
static class OOMObject {
public byte[] placeholder = new byte[64 * 1024];
}
/**
* 這段代碼的作用是以64kb/50毫秒的速度往java堆中填充資料,共填充1000次
* @param num
* @throws InterruptedException
*/
public static void fillHeap(int num) throws InterruptedException {
List<OOMObject> list = new ArrayList<OOMObject>();
for (int i = 0; i < num; i++) {
//稍作延時,令監視曲線的變化更加明顯
Thread.sleep(50);
list.add(new OOMObject());
}
System.gc();
}
public static void main(String[] args) throws InterruptedException {
fillHeap(1000);
}
}
檢視eden區的運作趨勢呈折線狀:
程式運作後,在“記憶體”頁簽中可以看到記憶體池eden區的運作趨勢呈現折線狀。而監視範圍擴大至整個
堆時,會發現曲線是一條向上增長的平滑曲線。并且從柱狀圖可以看到,在1000次循環執行結束,運作了
System.gc()後,雖然整個新生代Eden和Survivor區都基本被清空了,但是代表老年代的柱狀圖仍然保持峰值狀态,
說明被填充進堆中的資料在System.gc() 後,雖然整個新生代eden和survivor區都基本被清空了,但是代表老年代的柱狀圖
仍然保持峰值狀态,說明被填充進堆中的資料在System.gc()方法執行後仍然存活着。
為什麼執行了System.gc() 之後,老年代的柱狀圖仍然顯示為峰值狀态,代碼需要如何調整才能讓System.gc()回收掉填充到堆中的對象?
原因:System.gc()之後,空間未能回收是因為List<OOMObject> list 對象仍然存活着,fillHeap()方法仍然沒有退出,是以list對象在執行System.gc()時仍然處于作用域之内。如果把System.gc()移動到fillHeap()方法外,調用就可以回收掉
全部記憶體。