天天看點

JDK的指令行工具解析

1.jps :虛拟機程序狀況工具

-q 隻輸出LVMID,省略主類的名稱
-m 輸出虛拟機程序啟動時傳遞給主類main()函數的參數
-l 輸出主類全名,如果程序執行的是jar包,輸出jar路徑
-v 輸出虛拟機啟動時JVM參數
           

2.jstat:虛拟機統計資訊監視工具

參數: interval 查詢間隔  count  查詢次數
執行個體:
假設需要沒250毫秒查詢一次程序2764垃圾收集的狀況,一共查詢20次,指令為:

jstat -gc 2764 250 20
           

其他參數:

JDK的指令行工具解析

 3.jinfo : java配置資訊工具(實時檢視和調整虛拟機的各項參數。)

jinfo pid
           

4.jmap: java記憶體映像工具(用于生成堆轉儲快照)

jmap vmid
           

其他參數:

JDK的指令行工具解析

例子:生成一個正在運作的idea的dump快照檔案

jmap -dump:format=b,file=idea.bin 3500

5.jhat: 虛拟機堆轉儲快照分析工具

例子:

jhat idea.bin
           

分析結果顯示:

http://localhost:7000/

6.jstack: java 堆棧跟蹤工具(使用者生成虛拟機目前時刻的線程快照)

指令格式:

jstack [option] vmid

JDK的指令行工具解析

例子:

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區的運作趨勢呈折線狀:

JDK的指令行工具解析

程式運作後,在“記憶體”頁簽中可以看到記憶體池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()方法外,調用就可以回收掉

全部記憶體。