1. 程式人生 > >JVM 問題排查和效能優化常用的 JDK 工具

JVM 問題排查和效能優化常用的 JDK 工具

JDK 提供了一系列用於監控、診斷 Java 程序的工具,它們在 JDK 安裝目錄的 bin 目錄下,有 jps、jcmd、jstack、jinfo、jmap 等。其中jmc、jconsole、jvisualvm 是 GUI 工具,其他大部分都是命令列工具。

cd $JAVA_HOME/bin
ls

本篇只是個入門介紹,不涉及深入分析。每一個工具都有它專門的作用,掌握使用方法只是很簡單的入門階段,更重要的是根據工具得到的資訊去分析系統存在的問題以及效能瓶頸,每一個工具的使用和分析都可以單獨成文。

jps

如果你用過 Linux,那肯定熟悉 ps 命令,用來檢視程序列表的。jps 就好比是 ps 命令的子集,它查詢的是當前使用者下已經啟動的 Java 程序。這是進行線上問題排查的大門鑰匙,有了它才能下手後面的動作。

下面是 jps 的幫助文件

usage: jps [-help]
       jps [-q] [-mlvV] [<hostid>]

Definitions:
    <hostid>:      <hostname>[:<port>]

一般的用法是 jps -l,前面一列顯示 pid,後面一列顯示程序名稱。

還可以用下列引數檢視更具體的 Java 程序資訊,用法為 jps -lv

jstack

檢視 Java 程序內當前時刻的執行緒快照,也就是每條執行緒正在執行的方法棧情況,用於定位執行緒停頓、死鎖等長時間等待的問題。

以下是 jstack 的幫助文件。

Usage:
    jstack [-l] <pid>
        (to connect to running process)
    jstack -F [-m] [-l] <pid>
        (to connect to a hung process)
    jstack [-m] [-l] <executable> <core>
        (to connect to a core file)
    jstack [-m] [-l] [server_id@]<remote server IP or hostname>
        (to connect to a remote debug server)

Options:
    -F  to force a thread dump. Use when jstack <pid> does not respond (process is hung)
    -m  to print both java and native frames (mixed mode)
    -l  long listing. Prints additional information about locks
    -h or -help to print this help message

最常用的就是 jstack -pid 或者 jstack -l pid,列印執行緒狀態、棧使用情況。

如果是線上檢視不方便的話,可以用命令 jstack -l pid > stack.log,輸出到檔案中下載到本地檢視。

jstack -m pid,列印 Java 和 Native 棧資訊

如果 -l 和 -m 都不起作用的時候,可以使用 java -F pid 強制 dump。

jinfo

它的主要作用是檢視 JVM 配置引數,還可以動態設定部分引數值。jinfo 使用時需要 attach 到目標 JVM 上。關於 attach jvm 可以點選檢視 「Java 除錯工具、熱部署、JVM 監控工具都用到了它」

使用 jinfo -h檢視幫助文件

Usage:
    jinfo [option] <pid>
        (to connect to running process)
    jinfo [option] <executable <core>
        (to connect to a core file)
    jinfo [option] [server_id@]<remote server IP or hostname>
        (to connect to remote debug server)

where <option> is one of:
    -flag <name>         to print the value of the named VM flag
    -flag [+|-]<name>    to enable or disable the named VM flag
    -flag <name>=<value> to set the named VM flag to the given value
    -flags               to print VM flags
    -sysprops            to print Java system properties
    <no option>          to print both of the above
    -h | -help           to print this help message

jinfo -flags pid

檢視 JVM 引數,其中 Non-default VM flags 是虛擬機器預設設定的引數,Command line 是使用者指定的引數,比如命令列啟動 jar 包的時候加上的引數。

jinfo -flag 引數名 pid

可以檢視指定引數的值,比如檢視堆的最大值(-XX:MaxHeapSize 也就是 -Xmx ):

jinfo -flag MaxHeapSize 92041

-XX:MaxHeapSize=20971520

jinfo -sysprops pid

檢視系統引數

jinfo pid

檢視 jvm 引數和系統引數

以上資訊,如果我們用過 visualVM 等監控工具,一定非常熟悉。另外,我之前做過一個 web 版的 JVM 監控器,也實現了這個功能。

另外,還可以修改部分引數值。

jinfo -flag [+|-] pid

jinfo -flag = pid

可以修改部分 JVM 引數。

前者可以修改布林值引數,比如開啟簡單 GC 日誌

jinfo -flag +PrintGC 92041

後者是設定非布林值引數的,比如設定 HeapDumpPath

jinfo -flag HeapDumpPath=/users/fengzheng/jvmlog

哪些引數是允許動態修改的呢,用下面這個命令可以檢視

#Linux 和 Mac 
java -XX:+PrintFlagsInitial | grep manageable

#windows
java -XX:+PrintFlagsInitial | findstr manageable

jmap

jmap 檢視給定程序、核心檔案、遠端除錯伺服器的共享物件記憶體對映和堆記憶體細節的工具,可檢視堆使用情況、堆內物件直方圖、載入類、生成堆快照等。

Usage:
    jmap [option] <pid>
        (to connect to running process)
    jmap [option] <executable <core>
        (to connect to a core file)
    jmap [option] [server_id@]<remote server IP or hostname>
        (to connect to remote debug server)

where <option> is one of:
    <none>               to print same info as Solaris pmap
    -heap                to print java heap summary
    -histo[:live]        to print histogram of java object heap; if the "live"
                         suboption is specified, only count live objects
    -clstats             to print class loader statistics
    -finalizerinfo       to print information on objects awaiting finalization
    -dump:<dump-options> to dump java heap in hprof binary format
                         dump-options:
                           live         dump only live objects; if not specified,
                                        all objects in the heap are dumped.
                           format=b     binary format
                           file=<file>  dump heap to <file>
                         Example: jmap -dump:live,format=b,file=heap.bin <pid>
    -F                   force. Use with -dump:<dump-options> <pid> or -histo
                         to force a heap dump or histogram when <pid> does not
                         respond. The "live" suboption is not supported
                         in this mode.
    -h | -help           to print this help message
    -J<flag>             to pass <flag> directly to the runtime system

jmap -heap pid

列印 JVM 堆概要資訊,包括堆配置、新生代、老生代資訊

jmap -histo pid

列印類的直方圖,也就是各個類例項的個數和空間佔用情況。

如果加 :live,jamp -histo:live pid 則只打印活動類的資訊。這個命令會出發 GC 動作,會導致 JVM 停頓,所以在線上環境要慎用。

jmap -dump

dump 當前 JVM 堆,一般用法如下:

#dump 所有物件在堆中的分佈情況
jmap -dump:format=b,file=/Users/fengzheng/jvmlog/jamp_dump.hprof 95463

#加:live 引數 dump 存活物件在隊中的分佈情況
jmap -dump:live,format=b,file=/Users/fengzheng/jvmlog/jamp_dump.hprof 95463

之後再用堆分析工具,比如 visualVM、JProfile、MAT 等進行分析。和我們設定

-XX:+HeapDumpOnOutOfMemoryError 引數後,在發生 OOM 的時候 dump 的堆資訊是一樣的。

注意,dump 的過程會比較慢,在這個過程中會發生 JVM 停頓,而且在使用 :live 引數後,會觸發 GC 操作。

jmap -clstats pid

Java 類載入器(ClassLoader)資訊,包括載入器名稱、已載入類個數、佔用空間、父載入器、是否存活、型別資訊。

jmap -finalizerinfo pid

檢視等待被回收的物件。

jstat

jstat 主要用來通過垃圾回收相關資訊來判斷 JVM 效能問題,也可以檢視類載入、編譯的情況,主要的用法是通過持續的固定時間間隔的輸出來觀察。比如每 3 秒列印一次 GC 回收次數,連續列印 10 次,通過動態的變化來觀察 GC 是否過於密集。

下面是 jstat 的幫助手冊。

Usage: jstat -help|-options
       jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

Definitions:
  <option>      An option reported by the -options option
  <vmid>        Virtual Machine Identifier. A vmid takes the following form:
                     <lvmid>[@<hostname>[:<port>]]
                Where <lvmid> is the local vm identifier for the target
                Java virtual machine, typically a process id; <hostname> is
                the name of the host running the target Java virtual machine;
                and <port> is the port number for the rmiregistry on the
                target host. See the jvmstat documentation for a more complete
                description of the Virtual Machine Identifier.
  <lines>       Number of samples between header lines.
  <interval>    Sampling interval. The following forms are allowed:
                    <n>["ms"|"s"]
                Where <n> is an integer and the suffix specifies the units as 
                milliseconds("ms") or seconds("s"). The default units are "ms".
  <count>       Number of samples to take before terminating.
  -J<flag>      Pass <flag> directly to the runtime system.

通過 jstat -options 可以看到 jstat 支援檢視哪些資訊。

$ jstat -options
-class  #類載入情況 載入個數和空間使用
-compiler #即時編譯器資訊
-gc  # GC情況 包括 young gc、full gc 次數、時間等
-gccapacity #年輕代、老年代的使用情況
-gccause #GC 統計資訊和回收原因
-gcmetacapacity #顯示有關metaspace大小的統計資訊
-gcnew #新生代 GC 統計
-gcnewcapacity #新生代記憶體統計
-gcold #老年代 GC 統計
-gcoldcapacity #老年代記憶體使用情況
-gcutil #GC 彙總資訊
-printcompilation #編譯方法統計

上述這些大多數可以對應到 visualVM 的這一部分顯示

示例用法,如下是列印 5301 程序下的垃圾回收情況,-h 3 表示每 3 行輸出一次標題資訊,3s 5 表示每 3s 輸出一次,一共輸出 5 次

jstat -gcutil -h 3 5301 3s 5

最後輸出的內容如下:

jstat -gcutil -h 3 5301 3s 5
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
 99.92   0.00  11.90  35.29  94.96  94.08     34   12.675     3    1.946   14.621
 99.92   0.00  11.90  35.29  94.96  94.08     34   12.675     3    1.946   14.621
 99.92   0.00  11.90  35.29  94.96  94.08     34   12.675     3    1.946   14.621
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
 99.92   0.00  11.94  35.29  94.96  94.08     34   12.675     3    1.946   14.621
 99.92   0.00  11.94  35.29  94.96  94.08     34   12.675     3    1.946   14.621

jcmd

jcmd 會將命令傳送給 JVM。這些命令包括用於控制 Java Flight Recording(飛行記錄)、診斷命令等。 必須執行在 JVM 本地,不能遠端使用,並且必須用 JVM 啟動使用者執行。

通過 jps 命令找到一個 JVM 程序,然後使用下面的程式碼可以看到 jcmd 支援的命令

#程序 5173 
jcmd 5173 help 

5173:
The following commands are available:
JFR.stop
JFR.start
JFR.dump
JFR.check
VM.native_memory
VM.check_commercial_features
VM.unlock_commercial_features
ManagementAgent.stop
ManagementAgent.start_local
ManagementAgent.start
GC.rotate_log
Thread.print
GC.class_stats
GC.class_histogram
GC.heap_dump
GC.run_finalization
GC.run
VM.uptime
VM.flags
VM.system_properties
VM.command_line
VM.version
help

基本包含了問題排查的常用命令,並且和上面介紹的幾個工具有部分重合。

通過命令 jcmd 5173 help GC.heap_dump 可以查詢到 GC.heap_dump 命令的使用方法,其他命令都可以通過這個方法找到使用說明

jcmd 5173 help GC.heap_dump
5173:
GC.heap_dump
Generate a HPROF format dump of the Java heap.

Impact: High: Depends on Java heap size and content. Request a full GC unless the '-all' option is specified.

Permission: java.lang.management.ManagementPermission(monitor)

Syntax : GC.heap_dump [options] <filename>

Arguments:
    filename :  Name of the dump file (STRING, no default value)

Options: (options must be specified using the <key> or <key>=<value> syntax)
    -all : [optional] Dump all objects, including unreachable objects (BOOLEAN, false)

然後通過如下程式碼就可以 dump 堆資訊下來了,和 jmap -dump 的作用一樣

jcmd 5173 GC.heap_dump /Users/fengzheng/jvmlog/jcmd_heap_dump.hprof

拋磚引玉就到此了,之後會對 jinfo、jmap、jstack、jstat、jcmd 做詳細說明,記得關注啊。

相關閱讀:

JVM 你不可不知的引數

無意中就做了個 web 版 JVM 監控端

JConsole、VisualVM 依賴的 JMX 技術

Java 除錯工具、熱部署、JVM 監控工具都用到了它

我們說的 JVM 記憶體是什麼

歡迎關注,不定期更新本系列和其他文章
古時的風箏 ,進入公眾號可以加入交流群

相關推薦

JVM 問題排查效能優化常用JDK 工具

JDK 提供了一系列用於監控、診斷 Java 程序的工具,它們在 JDK 安裝目錄的 bin 目錄下,有 jps、jcmd、jstack、jinfo、jmap 等。其中jmc、jconsole、jvisualvm 是 GUI 工具,其他大部分都是命令列工具。 cd $JAVA_HOME/bin ls 本篇

JVM監控調優常用命令工具總結

JVM監控和調優 在Java應用和服務出現莫名的卡頓、CPU飆升等問題時總是要分析一下對應程序的JVM狀態以定位問題和解決問題並作出相應的優化,在這過程中Java自帶的一些狀態監控命令和圖形化工具就非常方便了。本文總結了最常用的命令列工具及其常用引數解釋,圖形化監控工具的用法,僅供參考。 jps Jav

JVM監控全體快三原始碼開發調優常用命令工具總結

JVM監控全體快三原始碼開發QQ2952777280【話仙原始碼論壇】hxforum.com和調優 在Java應用和服務出現莫名的卡頓、CPU飆升等問題時總是要分析一下對應程序的JVM狀態以定位問題和解決問題並作出相應的優化,在這過程中Java自帶的一些狀態監控

JAVA效能優化—IBM JDK JVM引數設定

本文將描述IBM JDK下常用引數的設定。  -Xms:最小堆大小   -Xmx:最大堆大小   -Xminf and -Xmaxf:GC(垃圾回收)之後可用空間的最小值最大值   -Xmine and -Xmaxe:堆增長的最小最大值   -Xmint and -Xmaxt

Apache Spark on K8s的安全性效能優化

前言     Apache Spark是目前最為流行的大資料計算框架,與Hadoop相比,它是替換MapReduce元件的不二選擇,越來越多的企業正在從傳統的MapReduce作業排程遷移到Spark上來,Spark的生態圈支持者越來越多,當然它出眾的內部API設計,讓它也

前端效能優化常用總結

前言 對於前端的效能話題,從來都沒有斷絕過。因為這個東西沒有最好,只有更好。而且往往也是業務的繁雜程度去決定優化程度的。作為一個前端開發者,效能是我們關注的指標。它直接影響著我們的使用者,同時也影響著產品本身。前端發展以來,優化方式,琳琅滿目,有雅虎軍規等。這些內容複雜繁多,往往容易被人遺忘。因

Centos7.3Samba4.7安裝效能優化

Centos7.3和Samba4.7安裝   1.系統環境: 系統:Centos 7.3.1611 x64位 服務版本:samba-4.7.1、samba-client-4.7.1   2.Samba 簡介 Samba 是在Linux和UNIX系統

Phoenix效能優化常用手段

1. 建表優化 Salting 翻譯成中文是加鹽的意思,本質是在hbase的rowkey的byte陣列的第一個位元組位置設定一個系統生成的byte值, 這個byte值是由主鍵生成rowkey的byte陣列做一個雜湊演算法,計算得來的。Salting之後可以把資料分佈到不同的region上

X86伺服器虛擬化的資源劃分效能優化

概述:虛擬化是一個廣義術語,通常是指計算元件在虛擬的基礎上而不是真實的基礎上執行,是一個為了簡化管理,優化資源的解決方案.伺服器虛擬化則是一項用以整合基於x86伺服器,來提高資源利用效率和效能的技術.本文從企業業務系統和管理角度出發,著重分析研究了X86技術架構下,虛擬網絡卡與SR-IOV、NUMA、虛擬磁碟

電商搜尋引擎的架構設計效能優化

轉載:https://blog.csdn.net/hu948162999/article/details/78861860 首先,我想說的是電商搜尋引擎和普通的搜尋引擎有很大的差別,因為電商搜尋引擎主要是解決使用者要“買什麼”,而通用搜索引擎主要是解決使用者“搜什麼

Apache Spark on K8s的安全幸運快三原始碼開發性效能優化

前言 Apache Spark是目前最為幸運快三原始碼開發QQ2952777280【話仙原始碼論壇】hxforum.com 流行的大資料計算框架,與Hadoop相比,它是替換MapReduce元件的不二選擇,越來越多的企業正在從傳統的MapReduce作業排程

第 15、16章 MySQL日誌效能優化

日誌分類: 錯誤日誌 查詢日誌 二進位制日誌 慢查詢日誌 二進位制日誌 啟動和設定二進位制日誌 首先找到mysql目錄下的my.ini,開啟它,找到[mysqld]組,新增以下幾個引數: 新增完畢後,重啟MySQL伺服器,便可查詢日誌設定: my

CSS 寫作建議效能優化小結

1.前言 還有幾天就到國慶中秋了,快要放假了,先祝大家節日快樂!之前寫過 JS 的寫作建議和技巧,那麼今天就來聊聊 CSS 吧! 說到 CSS,每一個網頁都離不開 CSS,但是對於 CSS,很多開發者的想法就是,CSS 只要能用來佈局,把效果圖排出來就可以了,其它的細節或

MySQL索引使用方法效能優化

關於MySQL索引的好處,如果正確合理設計並且使用索引的MySQL是一輛蘭博基尼的話,那麼沒有設計和使用索引的MySQL就是一個人力三輪車。對於沒有索引的表,單表查詢可能幾十萬資料就是瓶頸,而通常大型網站單日就可能會產生幾十萬甚至幾百萬的資料,沒有索引查詢會變的非常緩慢。還是

OpenCL入門:(三:GPU記憶體結構效能優化)

#include <iostream> #include <CL/cl.h> #include <cassert> #include <windows.h> #include <ctime> using namespace std; #defin

CSS寫作建議效能優化總結

今年難得遇到中秋和國慶,已經放假幾天了,我也回到家了。今天還是比較開心的,搶了比較多的紅包,嘿嘿。紅包搶完了,現在也空下來寫點部落格咯。 這裡是我從網上的一篇文章看過來的,這裡先做一點小結,之後再補充。 1.CSS渲染規則 今天在微博的一篇文章上看到的,之

ListView列表控制元件的介紹效能優化

ListView列表控制元件 一、ListView顯示資料的原理:mvc模式 m:mode 資料(用javabean規範封裝) v:view ListView c:adapter 介面卡,負責把資料展示到ListV

ListViewRecyclerView的使用效能優化總結

1.ListView介紹   在手機中,使用列表顯示是一種常見的顯示格式,那麼ListView就是一種常見的方式。例如:今日頭條,網易新聞都是使用ListView或者是最近流行的RecyclerView進行首頁的佈局,最後一節將會對它進行介紹。 2.L

效能優化Instruments-Leaks工具使用

效能優化中使用Instruments的Leaks工具進行記憶體洩露的檢測。 記憶體洩露,即記憶體被分配及使用過後,即使不再使用的該記憶體,也一直未被釋放,從而造成無法被其他物件使用。 在ARC記憶體管

Java記憶體優化效能優化的幾點建議

1.沒有必要時請不用使用靜態變數     使用Java的開發者都知道,當某個物件被定義為stataic變數所引用,這個物件所佔有的記憶體將不會被回收。有時,開發者會將經常呼叫的物件或者變數定義為static,以便提高程式的執行效能。因此,不是常用到的物件或者變數,不要定