JVM——JDK 監控和故障處理工具總結

文章目錄

    • JDK 命令行工具
      • `jps`:查看所有 Java 進程
      • `jstat`: 監視虛擬機各種運行狀態信息
      • ` jinfo`: 實時地查看和調整虛擬機各項參數
      • `jmap`:生成堆轉儲快照
      • **`jhat`**: 分析 heapdump 文件
      • **`jstack`** :生成虛擬機當前時刻的線程快照
    • JDK 可視化分析工具
      • JConsole:Java 監視與管理控制臺
        • 連接 Jconsole
        • 查看 Java 程序概況
        • 內存監控
        • 線程監控
      • Visual VM:多合一故障處理工具

JDK 命令行工具

這些命令在 JDK 安裝目錄下的 bin 目錄下:

  • jps (JVM Process Status): 類似 UNIX 的 ps 命令。用戶查看所有 Java 進程的啟動類、傳入參數和 Java 虛擬機參數等信息;
  • jstat( JVM Statistics Monitoring Tool): 用于收集 HotSpot 虛擬機各方面的運行數據;
  • jinfo (Configuration Info for Java) : Configuration Info forJava,顯示虛擬機配置信息;
  • jmap (Memory Map for Java) :生成堆轉儲快照;
  • jhat (JVM Heap Dump Browser ) : 用于分析 heapdump 文件,它會建立一個 HTTP/HTML 服務器,讓用戶可以在瀏覽器上查看分析結果;
  • jstack (Stack Trace for Java):生成虛擬機當前時刻的線程快照,線程快照就是當前虛擬機內每一條線程正在執行的方法堆棧的集合。

jps:查看所有 Java 進程

jps(JVM Process Status) 命令類似 UNIX 的 ps 命令。

jps:顯示虛擬機執行主類名稱以及這些進程的本地虛擬機唯一 ID(Local Virtual Machine Identifier,LVMID)。jps -q :只輸出進程的本地虛擬機唯一 ID。

C:\Users\SnailClimb>jps
7360 NettyClient2
17396
7972 Launcher
16504 Jps
17340 NettyServer

jps -l:輸出主類的全名,如果進程執行的是 Jar 包,輸出 Jar 路徑。

C:\Users\SnailClimb>jps -l
7360 firstNettyDemo.NettyClient2
17396
7972 org.jetbrains.jps.cmdline.Launcher
16492 sun.tools.jps.Jps
17340 firstNettyDemo.NettyServer

jps -v:輸出虛擬機進程啟動時 JVM 參數。

jps -m:輸出傳遞給 Java 進程 main() 函數的參數。

jstat: 監視虛擬機各種運行狀態信息

jstat(JVM Statistics Monitoring Tool) 使用于監視虛擬機各種運行狀態信息的命令行工具。 它可以顯示本地或者遠程(需要遠程主機提供 RMI 支持)虛擬機進程中的類信息、內存、垃圾收集、JIT 編譯等運行數據,在沒有 GUI,只提供了純文本控制臺環境的服務器上,它將是運行期間定位虛擬機性能問題的首選工具。

jstat 命令使用格式:

jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

比如 jstat -gc -h3 31736 1000 10表示分析進程 id 為 31736 的 gc 情況,每隔 1000ms 打印一次記錄,打印 10 次停止,每 3 行后打印指標頭部。

常見的 option 如下:

  • jstat -class vmid :顯示 ClassLoader 的相關信息;
  • jstat -compiler vmid :顯示 JIT 編譯的相關信息;
  • jstat -gc vmid :顯示與 GC 相關的堆信息;
  • jstat -gccapacity vmid :顯示各個代的容量及使用情況;
  • jstat -gcnew vmid :顯示新生代信息;
  • jstat -gcnewcapcacity vmid :顯示新生代大小與使用情況;
  • jstat -gcold vmid :顯示老年代和永久代的行為統計,從jdk1.8開始,該選項僅表示老年代,因為永久代被移除了;
  • jstat -gcoldcapacity vmid :顯示老年代的大小;
  • jstat -gcpermcapacity vmid :顯示永久代大小,從jdk1.8開始,該選項不存在了,因為永久代被移除了;
  • jstat -gcutil vmid :顯示垃圾收集信息;

另外,加上 -t參數可以在輸出信息上加一個 Timestamp 列,顯示程序的運行時間。

jinfo: 實時地查看和調整虛擬機各項參數

jinfo vmid :輸出當前 jvm 進程的全部參數和系統屬性 (第一部分是系統的屬性,第二部分是 JVM 的參數)。

jinfo -flag name vmid :輸出對應名稱的參數的具體值。比如輸出 MaxHeapSize、查看當前 jvm 進程是否開啟打印 GC 日志 ( -XX:PrintGCDetails :詳細 GC 日志模式,這兩個都是默認關閉的)。

C:\Users\SnailClimb>jinfo  -flag MaxHeapSize 17340
-XX:MaxHeapSize=2124414976
C:\Users\SnailClimb>jinfo  -flag PrintGC 17340
-XX:-PrintGC

使用 jinfo 可以在不重啟虛擬機的情況下,可以動態的修改 jvm 的參數。尤其在線上的環境特別有用,請看下面的例子:

jinfo -flag [+|-]name vmid 開啟或者關閉對應名稱的參數。

C:\Users\SnailClimb>jinfo  -flag  PrintGC 17340
-XX:-PrintGCC:\Users\SnailClimb>jinfo  -flag  +PrintGC 17340C:\Users\SnailClimb>jinfo  -flag  PrintGC 17340
-XX:+PrintGC

jmap:生成堆轉儲快照

jmap(Memory Map for Java)命令用于生成堆轉儲快照。 如果不使用 jmap 命令,要想獲取 Java 堆轉儲,可以使用 “-XX:+HeapDumpOnOutOfMemoryError” 參數,可以讓虛擬機在 OOM 異常出現之后自動生成 dump 文件,Linux 命令下可以通過 kill -3 發送進程退出信號也能拿到 dump 文件。

jmap 的作用并不僅僅是為了獲取 dump 文件,它還可以查詢 finalizer 執行隊列、Java 堆和永久代的詳細信息,如空間使用率、當前使用的是哪種收集器等。和jinfo一樣,jmap有不少功能在 Windows 平臺下也是受限制的。

示例:將指定應用程序的堆快照輸出到桌面。后面,可以通過 jhat、Visual VM 等工具分析該堆文件。

C:\Users\SnailClimb>jmap -dump:format=b,file=C:\Users\SnailClimb\Desktop\heap.hprof 17340
Dumping heap to C:\Users\SnailClimb\Desktop\heap.hprof ...
Heap dump file created

jhat: 分析 heapdump 文件

jhat 用于分析 heapdump 文件,它會建立一個 HTTP/HTML 服務器,讓用戶可以在瀏覽器上查看分析結果。

C:\Users\SnailClimb>jhat C:\Users\SnailClimb\Desktop\heap.hprof
Reading from C:\Users\SnailClimb\Desktop\heap.hprof...
Dump file created Sat May 04 12:30:31 CST 2019
Snapshot read, resolving...
Resolving 131419 objects...
Chasing references, expect 26 dots..........................
Eliminating duplicate references..........................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.

訪問 http://localhost:7000/

jstack :生成虛擬機當前時刻的線程快照

jstack(Stack Trace for Java)命令用于生成虛擬機當前時刻的線程快照。線程快照就是當前虛擬機內每一條線程正在執行的方法堆棧的集合.

生成線程快照的目的主要是定位線程長時間出現停頓的原因,如線程間死鎖、死循環、請求外部資源導致的長時間等待等都是導致線程長時間停頓的原因。線程出現停頓的時候通過jstack來查看各個線程的調用堆棧,就可以知道沒有響應的線程到底在后臺做些什么事情,或者在等待些什么資源。

下面是一個線程死鎖的代碼。我們下面會通過 jstack 命令進行死鎖檢查,輸出死鎖信息,找到發生死鎖的線程。

public class DeadLockDemo {private static Object resource1 = new Object();//資源 1private static Object resource2 = new Object();//資源 2public static void main(String[] args) {new Thread(() -> {synchronized (resource1) {System.out.println(Thread.currentThread() + "get resource1");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread() + "waiting get resource2");synchronized (resource2) {System.out.println(Thread.currentThread() + "get resource2");}}}, "線程 1").start();new Thread(() -> {synchronized (resource2) {System.out.println(Thread.currentThread() + "get resource2");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread() + "waiting get resource1");synchronized (resource1) {System.out.println(Thread.currentThread() + "get resource1");}}}, "線程 2").start();}
}

Output

Thread[線程 1,5,main]get resource1
Thread[線程 2,5,main]get resource2
Thread[線程 1,5,main]waiting get resource2
Thread[線程 2,5,main]waiting get resource1

線程 A 通過 synchronized (resource1) 獲得 resource1 的監視器鎖,然后通過 Thread.sleep(1000);讓線程 A 休眠 1s 為的是讓線程 B 得到執行然后獲取到 resource2 的監視器鎖。線程 A 和線程 B 休眠結束了都開始企圖請求獲取對方的資源,然后這兩個線程就會陷入互相等待的狀態,這也就產生了死鎖。

通過 jstack 命令分析:

C:\Users\SnailClimb>jps
13792 KotlinCompileDaemon
7360 NettyClient2
17396
7972 Launcher
8932 Launcher
9256 DeadLockDemo
10764 Jps
17340 NettyServerC:\Users\SnailClimb>jstack 9256

輸出的部分內容如下:

Found one Java-level deadlock:
=============================
"線程 2":waiting to lock monitor 0x000000000333e668 (object 0x00000000d5efe1c0, a java.lang.Object),which is held by "線程 1"
"線程 1":waiting to lock monitor 0x000000000333be88 (object 0x00000000d5efe1d0, a java.lang.Object),which is held by "線程 2"Java stack information for the threads listed above:
===================================================
"線程 2":at DeadLockDemo.lambda$main$1(DeadLockDemo.java:31)- waiting to lock <0x00000000d5efe1c0> (a java.lang.Object)- locked <0x00000000d5efe1d0> (a java.lang.Object)at DeadLockDemo$$Lambda$2/1078694789.run(Unknown Source)at java.lang.Thread.run(Thread.java:748)
"線程 1":at DeadLockDemo.lambda$main$0(DeadLockDemo.java:16)- waiting to lock <0x00000000d5efe1d0> (a java.lang.Object)- locked <0x00000000d5efe1c0> (a java.lang.Object)at DeadLockDemo$$Lambda$1/1324119927.run(Unknown Source)at java.lang.Thread.run(Thread.java:748)Found 1 deadlock.

可以看到 jstack 命令已經幫我們找到發生死鎖的線程的具體信息。

JDK 可視化分析工具

JConsole:Java 監視與管理控制臺

JConsole 是基于 JMX 的可視化監視、管理工具。可以很方便的監視本地及遠程服務器的 java 進程的內存使用情況。你可以在控制臺輸出console命令啟動或者在 JDK 目錄下的 bin 目錄找到jconsole.exe然后雙擊啟動。

連接 Jconsole

在這里插入圖片描述

如果需要使用 JConsole 連接遠程進程,可以在遠程 Java 程序啟動時加上下面這些參數:

-Djava.rmi.server.hostname=外網訪問 ip 地址 
-Dcom.sun.management.jmxremote.port=60001   //監控的端口號
-Dcom.sun.management.jmxremote.authenticate=false   //關閉認證
-Dcom.sun.management.jmxremote.ssl=false

在使用 JConsole 連接時,遠程進程地址如下:

外網訪問 ip 地址:60001 

查看 Java 程序概況

在這里插入圖片描述

內存監控

JConsole 可以顯示當前內存的詳細信息。不僅包括堆內存/非堆內存的整體信息,還可以細化到 eden 區、survivor 區等的使用情況,如下圖所示。

點擊右邊的“執行 GC(G)”按鈕可以強制應用程序執行一個 Full GC。

  • 新生代 GC(Minor GC):指發生新生代的的垃圾收集動作,Minor GC 非常頻繁,回收速度一般也比較快。
  • 老年代 GC(Major GC/Full GC):指發生在老年代的 GC,出現了 Major GC 經常會伴隨至少一次的 Minor GC(并非絕對),Major GC 的速度一般會比 Minor GC 的慢 10 倍以上。

在這里插入圖片描述

線程監控

類似我們前面講的 jstack 命令,不過這個是可視化的。

最下面有一個"檢測死鎖 (D)"按鈕,點擊這個按鈕可以自動為你找到發生死鎖的線程以及它們的詳細信息 。

在這里插入圖片描述

Visual VM:多合一故障處理工具

VisualVM 提供在 Java 虛擬機 (Java Virutal Machine, JVM) 上運行的 Java 應用程序的詳細信息。在 VisualVM 的圖形用戶界面中,您可以方便、快捷地查看多個 Java 應用程序的相關信息。Visual VM 官網:https://visualvm.github.io/ 。Visual VM 中文文檔:https://visualvm.github.io/documentation.html。

下面這段話摘自《深入理解 Java 虛擬機》。

VisualVM(All-in-One Java Troubleshooting Tool)是到目前為止隨 JDK 發布的功能最強大的運行監視和故障處理程序,官方在 VisualVM 的軟件說明中寫上了“All-in-One”的描述字樣,預示著他除了運行監視、故障處理外,還提供了很多其他方面的功能,如性能分析(Profiling)。VisualVM 的性能分析功能甚至比起 JProfiler、YourKit 等專業且收費的 Profiling 工具都不會遜色多少,而且 VisualVM 還有一個很大的優點:不需要被監視的程序基于特殊 Agent 運行,因此他對應用程序的實際性能的影響很小,使得他可以直接應用在生產環境中。這個優點是 JProfiler、YourKit 等工具無法與之媲美的。

VisualVM 基于 NetBeans 平臺開發,因此他一開始就具備了插件擴展功能的特性,通過插件擴展支持,VisualVM 可以做到:

  • 顯示虛擬機進程以及進程的配置、環境信息(jps、jinfo)。
  • 監視應用程序的 CPU、GC、堆、方法區以及線程的信息(jstat、jstack)。
  • dump 以及分析堆轉儲快照(jmap、jhat)。
  • 方法級的程序運行性能分析,找到被調用最多、運行時間最長的方法。
  • 離線程序快照:收集程序的運行時配置、線程 dump、內存 dump 等信息建立一個快照,可以將快照發送開發者處進行 Bug 反饋。
  • 其他 plugins 的無限的可能性…

這里就不具體介紹 VisualVM 的使用,如果想了解的話可以看:

  • https://visualvm.github.io/documentation.html
  • https://www.ibm.com/developerworks/cn/java/j-lo-visualvm/index.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/41269.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/41269.shtml
英文地址,請注明出處:http://en.pswp.cn/news/41269.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

手撕單鏈表

目錄 鏈表的概念和結構 單鏈表的實現 申請新結點 打印 尾插 頭插 尾刪 頭刪 ?編輯 查找 在pos位置前插入元素 在pos位置后插入元素 刪除pos位置的元素 刪除pos位置之后的位置的元素?編輯 完整代碼 SListNode.h SListNode.c 鏈表的概念和結構 鏈表是一種物理存儲…

【JavaSE】Java方法的使用

【本節目標】 1. 掌握方法的定義以及使用 2. 掌握方法傳參 3. 掌握方法重載 4. 掌握遞歸 目錄 1.方法概念及使用 1.1什么是方法(method) 1.2 方法定義 1.3 方法調用的執行過程 1.4 實參和形參的關系 2. 方法重載 2.1 為什么需要方法重載 2.2 方法重載概念 3. 遞歸 3.…

【uni-app報錯】獲取用戶收貨地址uni.chooseAddress()報錯問題

chooseAddress:fail the api need to be declared in …e requiredPrivateInf 原因&#xff1a; 小程序配置 / 全局配置 (qq.com) 解決&#xff1a; 登錄小程序后臺申請接口 按照流程申請即可 在項目根目錄中找到 manifest.json 文件&#xff0c;在左側導航欄選擇源碼視圖&a…

杭電比賽總結

我們的隊伍&#xff1a;team013 另外兩隊&#xff1a;team014、team015 ? 今天是我第一次打杭電&#xff0c;發現杭電多數都是猜結論題 先給一下我們的提交數據 Submit TimeProblem IDTimeMemoryJudge Status4:59:59101115 MS1692 KWrong Answer4:59:55101115 MS1684 KWrong…

Java算法_ 檢查對稱樹(LeetCode_Hot100)

題目描述&#xff1a;給你一個二叉樹的根節點 &#xff0c; 檢查它是否軸對稱。root 獲得更多&#xff1f;算法思路:代碼文檔&#xff0c;算法解析的私得。 運行效果 完整代碼 /*** 2 * Author: LJJ* 3 * Date: 2023/8/17 8:47* 4*/ public class SymmetricTree {static class…

vue之動態表單(優化)

代碼資源在這兒 ↑ vue之動態表單優化 vue2js動態表單優化vue3ts動態表單優化 vue2js動態表單優化 效果圖 目錄結構 五個文件的完整代碼: 以下是App.vue <template><div><router-view></router-view><Formpage /></div> </templa…

【LeetCode】647.回文子串

題目 給你一個字符串 s &#xff0c;請你統計并返回這個字符串中 回文子串 的數目。 回文字符串 是正著讀和倒過來讀一樣的字符串。 子字符串 是字符串中的由連續字符組成的一個序列。 具有不同開始位置或結束位置的子串&#xff0c;即使是由相同的字符組成&#xff0c;也會…

web連接桌面打開gptmap

一&#xff1a;環境配置 需要的材料&#xff1a; python-3.10.4 我使用的是這個版本的&#xff0c;3.8.10 該版本和以下版本組件組合&#xff0c;驗證過能正常運行&#xff08;python 3.6.8測試異常&#xff09; websockify 該項目有python版本和node js版本 noVNC 形式的app…

Qt Designer設計的界面如何顯示、即運行顯示窗口界面

首先利用Qt Designer設計.ui文件&#xff0c;然后采用Tools->External Tools->PyUIC轉換成.py文件。這個.py文件是.ui文件編譯而來的&#xff0c;將這種文件由.ui文件編譯而來的.py文件稱之為界面文件。由于界面文件每次編譯時候都會初始化&#xff0c;所以需要新建一個.…

Android 13 添加自定義分區,恢復出廠設置不被清除

需求: 客戶有些文件或數據,需要做得恢復出廠設置還存在,故需新增一個分區存儲客戶數據。 要求: a) 分區大小為50M b) 應用層可讀可寫 c) 恢復出廠設置后不會被清除 d) 不需要打包.img e) 不影響OTA升級 缺點: 1).通過代碼在分區創建目錄和文件,會涉及到SeLinux權限的修…

● 123.買賣股票的最佳時機III ● 188.買賣股票的最佳時機IV

123.買賣股票的最佳時機III class Solution { public:int maxProfit(vector<int>& prices) {vector<vector<int>>dp(prices.size(),vector<int>(5));int lenprices.size();if(len0)return 0;dp[0][0]0;dp[0][1]-prices[0];dp[0][2]0;dp[0][3]-pr…

LeetCode150道面試經典題-- 環形鏈表(簡單)

1.題目 給你一個鏈表的頭節點 head &#xff0c;判斷鏈表中是否有環。 如果鏈表中有某個節點&#xff0c;可以通過連續跟蹤 next 指針再次到達&#xff0c;則鏈表中存在環。 為了表示給定鏈表中的環&#xff0c;評測系統內部使用整數 pos 來表示鏈表尾連接到鏈表中的位置&…

Java設計模式 (一) 模板方法設計模式

什么是模板方法設計模式? 模板方法設計模式是一種行為型設計模式&#xff0c;它定義了一個算法的骨架&#xff0c;并將一些步驟的具體實現延遲到子類中。模板方法模式可以幫助確保在算法的不同部分中保持一致性&#xff0c;同時也允許子類根據需要進行具體實現。 模板方法模式…

分布式光伏運維平臺在公益場館屋頂光伏發電系統的應用分析

摘要&#xff1a;2021年9月&#xff0c;國家發改委印發烷善能源消費強度和總量雙控制度方案》&#xff0c;提出鼓勵可再生能源的使用&#xff0c;支持可再生能源發展。在這樣的政策推動下&#xff0c;光伏發電市場無疑將迎來高質量發展的新機遇。現結合山東博物館光伏電站日常管…

系統架構設計師---計算機基礎知識之數據庫系統結構與規范化

目錄 一、基本概念 二、 數據庫的結構 三、常用的數據模型 概念數據模型

git add 用法

git add 是 Git 的一個命令&#xff0c;用于將更改的文件加入到暫存區&#xff08;staging area&#xff09;&#xff0c;準備提交這些更改。以下是該命令的常見用法&#xff1a; 添加單個文件 git add 文件名添加多個文件 git add 文件名1 文件名2 ...添加所有當前目錄下的更改…

面試攻略,Java 基礎面試 100 問(十八)

JAVA IO 包 JAVA NIO NIO 主要有三大核心部分&#xff1a;Channel(通道)&#xff0c;Buffer(緩沖區), Selector。 傳統 IO 基于字節流和字 符流進行操作&#xff0c;而 NIO 基于 Channel 和 Buffer(緩沖區)進行操作&#xff0c;數據總是從通道讀取到緩沖區 中&#xff0c;或者…

Linux命令(70)之bzip2

linux命令之bzip2 1.bzip2介紹 linux命令bzip2是用來壓縮或解壓縮文件名后綴為".bz2"的文件 2.bzip2用法 bzip2 [參數] filename bzip2常用參數 參數說明-d解壓縮文件-t測試壓縮文件是否正確-k壓縮后&#xff0c;保留源文件-z強制壓縮-f強制覆蓋已存在的文件-v顯…

TRT8系列—— 版本差異注意事項

TRT8 一個大版本&#xff0c;8.4-、 8.5、 8.6&#xff08;包含預覽功能&#xff09;卻有很多變動&#xff0c;一不注意就發現很混亂&#xff0c;特備注此貼。建議具體case可以參考這個合集&#xff0c;真心安利&#xff1a;https://github.com/NVIDIA/trt-samples-for-hackath…

Go語言GIN框架安裝與入門

Go語言GIN框架安裝與入門 文章目錄 Go語言GIN框架安裝與入門1. 創建配置環境2. 配置環境3. 下載最新版本Gin4. 編寫第一個接口5. 靜態頁面和資源文件加載6. 各種傳參方式6.1 URL傳參6.2 路由形式傳參6.3 前端給后端傳遞JSON格式6.4 表單形式傳參 7. 路由和路由組8. 項目代碼mai…