JVM——性能監(jiān)控與故障處理工具

性能監(jiān)控與故障處理工具

命令行工具:jps、jinfo、jstack、jmap、jstat、jstatd、jcmd。

圖形化工具:JConsole、jmc、VisualVM。

兩種連接方式:JMX、jstatd。

JVM監(jiān)控工具的作用

  • 1、對(duì)JVM運(yùn)行期間的內(nèi)部情況進(jìn)行監(jiān)控,比如:對(duì)JVM參數(shù)、CPU、內(nèi)存、堆等信息的查看。

  • 2、輔助進(jìn)行性能調(diào)優(yōu)。

  • 3、輔助解決應(yīng)用運(yùn)行時(shí)的一些問題,比如:OutOfMemoryError、內(nèi)存泄漏、線程死鎖、鎖爭用、Java進(jìn)程消耗CPU過高等等。

jps:虛擬機(jī)進(jìn)程狀況工具

jps(JVM Process Status Tool)可以列出正在運(yùn)行的虛擬機(jī)進(jìn)程,并顯示虛擬機(jī)執(zhí)行主類(Main Class,main()函數(shù)所在的類)名稱以及這些進(jìn)程的本地虛擬機(jī)唯一ID(Local Virtual Machine Identifier,LVMID),即進(jìn)程ID。

jps命令格式

jps [options] [hostid]

參數(shù):
 -q:只輸出LVMID(進(jìn)程id),省略主類的名稱。

-m:數(shù)據(jù)虛擬機(jī)進(jìn)程啟動(dòng)時(shí)傳遞給主類main()函數(shù)的參數(shù)。

-l:輸出主類的全名,如果進(jìn)程執(zhí)行的是Jar包,輸出Jar路徑。

-v:數(shù)據(jù)虛擬機(jī)進(jìn)程啟動(dòng)時(shí)JVM參數(shù)。

命令格式的各種參數(shù)的含義就不再解釋,主要介紹一下常見的用法,有想深入了解的去看上面地址的官方文檔

jps可以通過RMI(Remote Method Invocation,遠(yuǎn)程方法調(diào)用)協(xié)議查詢開啟了RMI服務(wù)的遠(yuǎn)程虛擬機(jī)進(jìn)程狀態(tài),hostid為RMI注冊表中注冊的主機(jī)名。

不指定hostid就默認(rèn)為當(dāng)前主機(jī)或服務(wù)器。

jinfo:Java配置信息工具

jinfo(Configuration Info for Java)的作用是實(shí)時(shí)地查看和調(diào)整虛擬機(jī)各項(xiàng)參數(shù)。 使用jps命令的-v參數(shù)可以查看虛擬機(jī)啟動(dòng)時(shí)顯式指定的參數(shù)列表,但如果想知道未被顯式指定的參數(shù)的系統(tǒng)默認(rèn)值,除了去找資料外,就只能使用jinfo的-flag選項(xiàng)進(jìn)行查詢了(如果只限于JDK 1.6或以上版本的話,使用java-XX:+PrintFlagsFinal查看參數(shù)默認(rèn)值也是一個(gè)很好的選擇)

jinfo 命令格式

jinfo [ option ] pid

參數(shù):
-v:查看虛擬機(jī)啟動(dòng)時(shí)顯式指定的參數(shù)列表。

-flag name:打印指定java虛擬機(jī)的參數(shù)值。

-flag name=value:修改一部分運(yùn)行期可修改的虛擬機(jī)參數(shù)值。

-flag [+|-]name:設(shè)置或取消指定java虛擬機(jī)參數(shù)的布爾值。

jstack:Java堆棧跟蹤工具

jstack(Stack Trace for Java)命令用于生成虛擬機(jī)當(dāng)前時(shí)刻的線程快照(一般稱為threaddump或者javacore文件),即查看某個(gè)Java進(jìn)程內(nèi)的線程堆棧信息。

線程快照就是當(dāng)前虛擬機(jī)內(nèi)每一條線程正在執(zhí)行的方法堆棧的集合,生成線程快照的主要目的是定位線程出現(xiàn)長時(shí)間停頓的原因,如線程間死鎖、 死循環(huán)、 請求外部資源導(dǎo)致的長時(shí)間等待等都是導(dǎo)致線程長時(shí)間停頓的常見原因。 線程出現(xiàn)停頓的時(shí)候通過jstack來查看各個(gè)線程的調(diào)用堆棧,就可以知道沒有響應(yīng)的線程到底在后臺(tái)做些什么事情,或者等待著什么資源。

jstack命令格式

jstack [ options ] pid

參數(shù):
-F:當(dāng)正常輸出的請求不被響應(yīng)時(shí),強(qiáng)制輸出線程堆棧。

-l:除了堆棧外,顯示關(guān)于鎖的附加信息。

-m:顯示本地方法的堆棧(C/C++)。

jmap:Java內(nèi)存映像工具

jmap(Memory Map for Java)命令用于生成堆轉(zhuǎn)儲(chǔ)快照(一般稱為heapdump或dump文件)。 如果不使用jmap命令,要想獲取Java堆轉(zhuǎn)儲(chǔ)快照,還有一些比較“暴力”的手段:譬如-XX:+HeapDumpOnOutOfMemoryError參數(shù),可以讓虛擬機(jī)在OOM異常出
現(xiàn)之后自動(dòng)生成dump文件,通過-XX:+HeapDumpOnCtrlBreak參數(shù)則可以使用[Ctrl]+[Break]鍵讓虛擬機(jī)生成dump文件,又或者在Linux系統(tǒng)下通過Kill-3命令發(fā)送進(jìn)程退出信號(hào)“嚇?!币幌绿摂M機(jī),也能拿到dump文件。

jmap命令格式

jmap [ options ] pid

參數(shù):
-dump:生成Java堆轉(zhuǎn)儲(chǔ)快照。格式為: -dump:[live,]format=b,file=<filename>,其中l(wèi)ive子參數(shù)說明是否只dump出存活的對(duì)象。

-heap:顯示java堆詳細(xì)信息,如使用哪種回收器,參數(shù)配置,分帶狀況等。只在Linux/Solaris平臺(tái)下有效。

-histo:顯示堆中對(duì)象統(tǒng)計(jì)信息,包括類,實(shí)例數(shù)量,合計(jì)容量。

-F:當(dāng)虛擬機(jī)進(jìn)程對(duì)-dump選項(xiàng)沒有響應(yīng)時(shí),可使用這個(gè)選項(xiàng)強(qiáng)制生成dump快照。只在Linux/Solaris平臺(tái)下有效。

jstat:虛擬機(jī)統(tǒng)計(jì)信息監(jiān)視工具

jstat(JVM Statistics Monitoring Tool)是用于監(jiān)視虛擬機(jī)各種運(yùn)行狀態(tài)信息的命令行工具。 它可以顯示本地或者遠(yuǎn)程虛擬機(jī)進(jìn)程中的類裝載、 內(nèi)存、 垃圾收集、 JIT編譯等運(yùn)行數(shù)據(jù),在沒有GUI圖形界面,只提供了純文本控制臺(tái)環(huán)境的服務(wù)器上,它將是運(yùn)行期定位虛擬機(jī)性能問題的首選工具。

jstat命令格式

jstat [ generalOption | outputOptions vmid [ interval[s|ms] [ count ] ]

參數(shù):
-class:監(jiān)視類裝載,卸載數(shù)量,總空間以及類裝載鎖消耗的時(shí)間。

-gc:監(jiān)視Java堆狀況,包括Eden區(qū),兩個(gè)survivor區(qū),老年代,永久代的容量,已用空間,GC時(shí)間合計(jì)等信息。

-gcutil:監(jiān)視內(nèi)容與-gc基本相同,但輸出主要關(guān)注已使用空間占總空間的百分比。

-gcnew:監(jiān)視新生代GC狀況。

-gcold:監(jiān)視老年代GC狀況。

-compiler:輸出JIT編譯器編譯過的方法,耗時(shí)等信息。

-printcompilation:輸出已經(jīng)被JIT編譯的方法。

jstatd:即虛擬機(jī)的jstat守護(hù)進(jìn)程

jstatd,即虛擬機(jī)的jstat守護(hù)進(jìn)程,主要用于監(jiān)控JVM的創(chuàng)建與終止,并提供一個(gè)接口允許遠(yuǎn)程監(jiān)控工具依附到在本地主機(jī)上運(yùn)行的JVM。

jstatd工具是一個(gè)RMI服務(wù)器應(yīng)用程序,主要用于監(jiān)控HotSpot Java 虛擬機(jī)的創(chuàng)建與終止,并提供一個(gè)接口以允許遠(yuǎn)程監(jiān)控工具附加到本地主機(jī)上運(yùn)行的JVM上。

jstatd服務(wù)器需要在本地主機(jī)上存在一個(gè)RMI注冊表。jstatd服務(wù)器將嘗試在默認(rèn)端口或-p port選項(xiàng)指定的端口附加到該RMI注冊表上。如果RMI注冊表不存在,jstatd應(yīng)用程序?qū)?huì)自動(dòng)創(chuàng)建一個(gè),并綁定到-p port選項(xiàng)指定的端口上,如果省略了-p port選項(xiàng),則綁定到默認(rèn)的RMI注冊表端口。你可以通過指定-nr選項(xiàng)來抑制內(nèi)部RMI注冊表的創(chuàng)建。

注意:此工具是不受支持的,并且無法確定在未來版本的JDK中是否可用。目前,此工具不適用于Windows 98和Windows ME平臺(tái)。

jstatd命令格式

jstatd [ options ]

參數(shù):
-nr:當(dāng)找不到現(xiàn)有的RMI注冊表時(shí),不嘗試使用jstatd進(jìn)程創(chuàng)建一個(gè)內(nèi)部的RMI注冊表。

-p  port:在指定的端口查找RMI注冊表。如果沒有找到,并且沒有指定-nr選項(xiàng),則在該端口自行創(chuàng)建一個(gè)內(nèi)部的RMI注冊表。

-n  rminame:RMI注冊表中綁定的RMI遠(yuǎn)程對(duì)象的名稱。默認(rèn)的名稱為JStatRemoteHost。如果多個(gè)jstatd服務(wù)器在同一主機(jī)上運(yùn)行,你可以通過指定該選項(xiàng)來讓每個(gè)服務(wù)器導(dǎo)出的RMI對(duì)象具有唯一的名稱。不管如何,這樣做需要將唯一的服務(wù)器名稱包含進(jìn)監(jiān)控客戶端的hostid和vmid字符串中。

-Joption:將選項(xiàng)參數(shù)傳遞給被javac調(diào)用的java啟動(dòng)程序。例如,-J-Xms48m設(shè)置啟動(dòng)內(nèi)存為48 MB。使用-J將選項(xiàng)參數(shù)傳遞給執(zhí)行Java應(yīng)用程序的底層虛擬機(jī),這是一種常見慣例。

jcmd:JVM診斷命令行工具

JDK7 update 4,新增了一個(gè)jcmd診斷命令行工具,它是一個(gè)多功能的工具,將診斷命令請求發(fā)送到正在運(yùn)行的Java虛擬機(jī),可以導(dǎo)出堆棧,查看jvm進(jìn)程,導(dǎo)出線程信息,執(zhí)行GC等。

jcmd沒有提供遠(yuǎn)程方法方式,只能查看本地的jvm信息:

jcmd <pid | main class> <command ...|PerfCounter.print|-f file>

參數(shù)含義:
jcmd PID VM.uptime:查看 JVM 的啟動(dòng)時(shí)長。

jcmd PID GC.class_histogram:查看 JVM 的類信息,這個(gè)可以查看每個(gè)類的實(shí)例數(shù)量和占用空間大小。

jcmd PID Thread.print:查看 JVM 的Thread Dump。

jcmd PID GC.heap_dump FILE_NAME:查看 JVM 的Heap Dump,注意,如果只指定文件名,默認(rèn)會(huì)生成在啟動(dòng) JVM 的目錄里。

jcmd PID VM.system_properties:查看 JVM 的屬性信息。

jcmd PID VM.flags:查看 JVM 的啟動(dòng)參數(shù),注意,可以看到 -X 和 -XX 的參數(shù)信息。

jcmd PID VM.command_line:查看 JVM 的啟動(dòng)命令行。

jcmd PID GC.run_finalization:對(duì) JVM 執(zhí)行 java.lang.System.runFinalization(),盡量b別去調(diào)用這個(gè)對(duì)象的finalize方法。

jcmd PID GC.run:對(duì) JVM 執(zhí)行 java.lang.System.gc(),告訴垃圾收集器打算進(jìn)行垃圾收集,而垃圾收集器進(jìn)不進(jìn)行收集是不確定的。

jcmd PID PerfCounter.print:查看 JVM 的性能。

JConsole:基于JMX的可視化監(jiān)視、管理工具

Jconsole (Java Monitoring and Management Console),JDK自帶的,一種基于JMX的可視化監(jiān)視、管理工具。

可以在系統(tǒng)有一定負(fù)荷的情況下使用;對(duì)垃圾回收算法有很詳細(xì)的跟蹤。

jconsole [ -interval=n ] [ -notile ] [ -pluginpath <path> ] [ -version ] [ connection ... ]

  -interval:將更新間隔設(shè)置為 n 秒 (默認(rèn)值為 4 秒)
  -notile:初始不平鋪窗口 (對(duì)于兩個(gè)或多個(gè)連接)
  -pluginpath:指定 jconsole 用于查找插件的路徑
  -version:輸出程序版本

  connection = pid || host:port || JMX URL (service:jmx:<協(xié)議>://...)
  pid         目標(biāo)進(jìn)程的進(jìn)程 ID
  host        遠(yuǎn)程主機(jī)名或 IP 地址
  port        遠(yuǎn)程連接的端口號(hào)

  -J          指定運(yùn)行 jconsole 的 Java 虛擬機(jī)的輸入?yún)?shù)

執(zhí)行命令后,打開新建連接窗口,有兩種

  • 1)本地進(jìn)程
  • 2)遠(yuǎn)程進(jìn)程

1、概述

顯示有關(guān)Java VM和監(jiān)視值的概述信息,包括CPU使用情況,內(nèi)存使用情況,線程計(jì)數(shù)以及Java VM中加載的類的圖形監(jiān)視信息


2、內(nèi)存

顯示有關(guān)內(nèi)存消耗和內(nèi)存池的信息


“內(nèi)存”選項(xiàng)卡具有“執(zhí)行GC”按鈕,可以隨時(shí)單擊該按鈕以執(zhí)行垃圾回收。

該圖表顯示了Java VM隨時(shí)間的內(nèi)存使用情況,堆和非堆內(nèi)存以及特定內(nèi)存池的內(nèi)存使用情況。

Java VM管理兩種內(nèi)存:堆內(nèi)存和非堆內(nèi)存,這兩種內(nèi)存都是在Java VM啟動(dòng)時(shí)創(chuàng)建的。

  • 1)堆內(nèi)存是運(yùn)行時(shí)數(shù)據(jù)區(qū),Java VM從中為所有類實(shí)例和數(shù)組分配內(nèi)存。堆可以是固定的或可變的大小。垃圾收集器是一個(gè)自動(dòng)內(nèi)存管理系統(tǒng),可回收對(duì)象的堆內(nèi)存。
    • A.Eden Space:
      伊甸區(qū),對(duì)象被創(chuàng)建的時(shí)候首先放到Eden Space,進(jìn)行垃圾回收后,不能被回收的對(duì)象被放入到空的Survivor區(qū)域
    • B.Survivor Space:
      幸存者區(qū),用于保存在eden space內(nèi)存區(qū)域中經(jīng)過垃圾回收后沒有被回收的對(duì)象
      Survivor Space分為兩個(gè)空間大小一樣的區(qū)域,分別是To Survivor和From Survivor,并且始終保持一個(gè)Survivor是空的

Eden Space和Survivor Space都屬于新生代

對(duì)新生代 進(jìn)行垃圾回收被稱為Minor GC(或Young GC),每一次Minor GC后留下來的對(duì)象age(就是用來判斷對(duì)象是否進(jìn)入老年的標(biāo)志)加1

* C.Old Gen:
老年代,用于存放新生代中經(jīng)過多次垃圾回收仍然存活的對(duì)象,也有可能是新生代分配不了內(nèi)存的大對(duì)象會(huì)直接進(jìn)入老年代。
經(jīng)過多次垃圾回收都沒有被回收的對(duì)象,這些對(duì)象的age已經(jīng)足夠old了,就會(huì)放入到老年代。
當(dāng)老年代被放滿之后,虛擬機(jī)會(huì)進(jìn)行垃圾回收,稱之為Major GC。由于Major GC除并發(fā)GC外均需對(duì)整個(gè)堆進(jìn)行掃描和回收,因此又稱為Full GC

堆內(nèi)存默認(rèn)為物理內(nèi)存的1/64(<1GB);默認(rèn)空余堆內(nèi)存小于40%時(shí),JVM就會(huì)增大堆直到-Xmx的最大限制,可以通過MinHeapFreeRatio參數(shù)進(jìn)行調(diào)整;默認(rèn)空余堆內(nèi)存大于70%時(shí),JVM會(huì)減少堆直到-Xms的最小限制,可以通過MaxHeapFreeRatio參數(shù)進(jìn)行調(diào)整。

  • 2)非堆內(nèi)存包括在Java VM的內(nèi)部處理或優(yōu)化所需的所有線程和內(nèi)存之間共享的方法區(qū)域。

它存儲(chǔ)每類結(jié)構(gòu),例如運(yùn)行時(shí)常量池,字段和方法數(shù)據(jù),以及方法和構(gòu)造函數(shù)的代碼。

方法區(qū)域在邏輯上是堆的一部分,但是根據(jù)實(shí)現(xiàn),Java VM可能不會(huì)垃圾收集或壓縮它。

與堆存儲(chǔ)器一樣,方法區(qū)域可以是固定的或可變的大小。方法區(qū)域的內(nèi)存不需要是連續(xù)的。

* A.Metaspace:
元空間,是方法區(qū)的在HotSpot jvm 中的實(shí)現(xiàn),方法區(qū)主要用于存儲(chǔ)類的信息、常量池、方法數(shù)據(jù)、方法代碼等。方法區(qū)邏輯上屬于堆的一部分,但是為了與堆進(jìn)行區(qū)分,通常又叫“非堆”。

* B.Code Cache:
HotSpot Java VM還包括代碼緩存,其中包含用于編譯和存儲(chǔ)本機(jī)代碼的內(nèi)存。

* C.Compressed Class Space:壓縮類空間

3、線程

顯示有關(guān)線程使用的信息


紅色:峰值線程數(shù),藍(lán)色:活動(dòng)線程數(shù)。

左下角的線程列表列出了所有活動(dòng)線程

單擊“線程”列表中的線程名稱,以顯示有關(guān)該線程的信息,包括線程名稱,狀態(tài)和堆棧跟蹤。

4、類監(jiān)控加載

顯示有關(guān)類加載的信息


紅線是加載的類的總數(shù)(包括隨后卸載的類),藍(lán)線是當(dāng)前加載的類的數(shù)量。

“詳細(xì)信息”部分顯示自Java VM啟動(dòng)以來加載的類的總數(shù),當(dāng)前加載的數(shù)量和卸載的數(shù)量。

通過選中右上角的復(fù)選框?qū)㈩惣虞d跟蹤設(shè)置為詳細(xì)輸出

5、VM信息

提供有關(guān)Java VM的信息


6、MBean

顯示了所有在platform. MBeanserver上注冊的MBeans的信息

左邊的樹形結(jié)構(gòu)顯示了所有的MBean

選擇了一個(gè)MBean之后,其屬性、操作、通知和其他信息會(huì)在右邊顯示

兩種遠(yuǎn)程連接方式

  • JMX連接可以查看:系統(tǒng)信息、CPU使用情況、線程多少、手動(dòng)執(zhí)行垃圾回收等比較偏于系統(tǒng)層面的信息。

  • jstatd連接方式可以提供:JVM內(nèi)存分布詳細(xì)信息、垃圾回收分布圖、線程詳細(xì)信息、甚至可以看到某個(gè)對(duì)象使用內(nèi)存的大小。

遠(yuǎn)程連接Tomcat

  • 配置JMX的支持,需要在tomcat的catalina.sh里面添加一些設(shè)置:
    修改Tomcat下的bin/catalina.sh文件,搜索 Execute The Requested Command ,在下方添加以下內(nèi)容(ip修改成自己的):
CATALINA_OPTS="$CATALINA_OPTS 
    -Dcom.sun.management.jmxremote=true
    -Djava.rmi.server.hostname=10.1.1.52 
    -Dcom.sun.management.jmxremote.port=1099 
    -Dcom.sun.management.jmxremote.ssl=false 
    -Dcom.sun.management.jmxremote.authenticate=false"

需要開啟鑒權(quán)功能(用戶密碼登錄監(jiān)視),修改成以下內(nèi)容:

CATALINA_OPTS="$CATALINA_OPTS 
    -Dcom.sun.management.jmxremote=true 
    -Djava.rmi.server.hostname=10.1.1.52 
    -Dcom.sun.management.jmxremote.port=1099 
    -Dcom.sun.management.jmxremote.ssl=false 
    -Dcom.sun.management.jmxremote.authenticate=true 
    -Dcom.sun.management.jmxremote.password.file=../conf/jmxremote.password 
    -Dcom.sun.management.jmxremote.access.file=../conf/jmxremote.access"
server.hostname:ip
jmxremote.port:開啟jmx的端口
jmxremote.ssl:是否開啟ssl(false/true)
jmxremote.authenticate:是否開啟鑒權(quán)功能,賬號(hào)密碼遠(yuǎn)程監(jiān)控(false/true)
jmxremote.password.file:密碼文件路徑
jmxremote.access.file:權(quán)限文件路徑

創(chuàng)建文件

touch jmxremote.password jmxremote.access
在JAVA_HOME\jre\lib\management下有模板

jmxremote.password文件添加以下內(nèi)容:

#(123456、123456789為密碼)
monitorRole 123456 
controlRole 123456789

jmxremote.access文件添加以下內(nèi)容:

monitorRole   readonly
controlRole   readwrite

新建完成這兩個(gè)文件要修改jmxremote.password的權(quán)限

#賦值權(quán)限
chmod 600 jmxremote.password

配置jstatd(jdk13):1、自定義一個(gè)statd.policy文件,添加:

grant codebase "jrt:/jdk.jstatd" {
    permission java.security.AllPermission;
};

grant codebase "jrt:/jdk.internal.jvmstat" {
    permission java.security.AllPermission;
};  

然后在JDK_HOME/bin下面運(yùn)行jstatd,示例如:

./jstatd -J -Djava.rmi.server.hostname=192.168.1.102 -J -Djava.security.policy=java.policy=java.policy -p 1099 &

參考:
https://blog.csdn.net/zzti_erlie/article/details/86517158

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容