java應(yīng)用監(jiān)測(3)-這些命令行工具你掌握了嗎

tags: java, troubleshooting, monitor,jvm


一句話概括:原來jdk自帶的命令行工具如此好用,本文將詳細(xì)介紹。

1 引言

監(jiān)測java應(yīng)用,最方便的就是直接使用jdk提供的現(xiàn)成工具,在jdk的安裝的bin目錄下,已經(jīng)提供了多種命令行監(jiān)測工具,以便于開發(fā)人員和運(yùn)維人員監(jiān)測java應(yīng)用和診斷問題,因此,此類工具是java應(yīng)用監(jiān)測的重要手段。也是作為java開發(fā)人員需要掌握的基本技能。

2 常用監(jiān)測命令行工具

一般來說,常用的命令行工具包括jps,jinfo,jmap,jstack,jstat,這些工具都在JAVA_HOME/bin/目錄下,概要說明如下:

  • jps查看java進(jìn)程ID
  • jinfo查看及調(diào)整虛擬機(jī)參數(shù)
  • jmap查看堆(heap)使用情況及生成堆快照
  • jstack查看線程運(yùn)行狀態(tài)及生成線程快照
  • jstat顯示進(jìn)程中的類裝載、內(nèi)存、垃圾收集等運(yùn)行數(shù)據(jù)。

通過這些工具,基本上可以了解java應(yīng)用的內(nèi)存變化狀態(tài),線程運(yùn)行狀態(tài)等信息,進(jìn)而為應(yīng)用監(jiān)測及問題診斷提供依據(jù)。下面將結(jié)合實(shí)例對(duì)這些工具的使用進(jìn)行詳細(xì)講解,文中所使用的示例代碼java-monitor-example已上傳到我的github,地址:https://github.com/mianshenglee。

3 進(jìn)程查詢工具jps

3.1 jps說明

要監(jiān)測java應(yīng)用,第一步就是先知道這個(gè)應(yīng)用是哪個(gè)進(jìn)程,它的運(yùn)行參數(shù)是什么。jps就是可以查詢進(jìn)程的工具。熟悉linux的同學(xué),大概都知道查詢進(jìn)程使用ps -ef|grep java這樣的命令,jps也類似,但它不使用名稱查找,而是查找全部當(dāng)前jdk運(yùn)行的java進(jìn)程,而且只查找當(dāng)前用戶的Java進(jìn)程,而不是當(dāng)前系統(tǒng)中的所有進(jìn)程。

3.2 jps使用

作為命令行工具,可以通過-help參數(shù)查看幫助,也可查閱官方文檔https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jps.html,如下:

[root@test bin]# jps -help
usage: jps [-help]
       jps [-q] [-mlvV] [<hostid>]

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

參數(shù)解釋:
-q:只顯示java進(jìn)程的pid
-m:輸出傳遞給main方法的參數(shù),在嵌入式j(luò)vm上可能是null
-l:輸出應(yīng)用程序main class的完整package名 或者 應(yīng)用程序的jar文件完整路徑名
-v:輸出傳遞給JVM的參數(shù)

示例工程java-monitor-example在linux機(jī)器中運(yùn)行起來,使用jps可輸出以下信息:

  • 只輸出進(jìn)程ID
[root@test bin]# jps -q
13680
14214
  • 輸出程序完整名稱及JVM參數(shù)
[root@test bin]# jps -lv
13680 java-monitor-example-0.0.1-SNAPSHOT.jar -Xms128m -Xmx128m -Dserver.port=8083
14289 sun.tools.jps.Jps -Denv.class.path=.:/opt/jdk8/lib:/opt/jdk8/jre/lib -Dapplication.home=/opt/jdk8

輸出的內(nèi)容中,java-monitor-example-0.0.1-SNAPSHOT.jar-l輸出的完整名稱,-Xms128m -Xmx128m -Dserver.port=8083是傳給JVM的參數(shù)。

  • 在shell腳本中使用命令獲取java進(jìn)程ID并作為變量使用
JAVA_HOME="/opt/jdk8"
APP_MAINCLASS=java-monitor-example
#初始化psid變量(全局)
psid=0

#查看進(jìn)程ID函數(shù)
checkpid() {
   javaps=`$JAVA_HOME/bin/jps -l | grep $APP_MAINCLASS`
 
   if [ -n "$javaps" ]; then
      psid=`echo $javaps | awk '{print $1}'`
   else
      psid=0
   fi
}

#調(diào)用函數(shù)后通過psid進(jìn)行業(yè)務(wù)邏輯操作,如根據(jù)進(jìn)程id殺進(jìn)程
checkpid
echo "(pid=$psid)"

上述腳本,比較適合運(yùn)維人員對(duì)應(yīng)用的開啟和關(guān)閉,自動(dòng)獲取java進(jìn)程ID,然后根據(jù)ID判斷程序是否運(yùn)行(start),或者關(guān)閉應(yīng)用(kill -9)。

4 配置信息工具jinfo

4.1 jinfo說明

知道java應(yīng)用所屬的進(jìn)程號(hào)是第一步,在上一篇文章《java應(yīng)用監(jiān)測(2)-java命令的秘密》中,已經(jīng)知道java的啟動(dòng)參數(shù)有很多,監(jiān)測java應(yīng)用前需要了解清楚它的啟動(dòng)參數(shù)是什么。這時(shí)就需要用到jinfo工具。jinfo可以輸出JAVA應(yīng)用的系統(tǒng)參數(shù)和JVM參數(shù)。jinfo還能夠修改一部分運(yùn)行期間能夠調(diào)整的虛擬機(jī)參數(shù),很多運(yùn)行參數(shù)是不能調(diào)整的,如果出現(xiàn)"cannot be changed"異常,說明不能調(diào)整。不過官方文檔指出,這個(gè)命令在后續(xù)的版本中可能不再使用,當(dāng)前JDK8還是可以用的。

4.2 jinfo使用

通過-help參數(shù)查看幫助,也可查閱jinfo官方文檔說明https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jinfo.html,如下:

[root@test bin]# jinfo -help
Usage:
    jinfo [option] <pid>
        (to connect to running process)

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

使用jps獲取到應(yīng)用的進(jìn)程ID后(示例的PID為13680),如果直接jps <pid>則會(huì)輸出全部的系統(tǒng)參數(shù)和JVM參數(shù),其它參數(shù)說明在help中也說得很清楚了。下面還是結(jié)合示例代碼java-monitor-example來實(shí)踐一下:

  • 獲取java應(yīng)用的堆初始值
[root@test bin]# jinfo -flag InitialHeapSize 13680
-XX:InitialHeapSize=134217728
  • 查看全部的JVM參數(shù)
[root@test bin]# jinfo -flags 13680
Attaching to process ID 13680, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.51-b03
Non-default VM flags: -XX:CICompilerCount=2 -XX:InitialHeapSize=134217728 -XX:MaxHeapSize=134217728 -XX:MaxNewSize=44564480 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=44564480 -XX:OldSize=89653248 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC
Command line:  -Xms128m -Xmx128m -Dserver.port=8083

可見,由于我們啟動(dòng)時(shí)設(shè)置了-Xms-Xmx,它們對(duì)應(yīng)的就是-XX:InitialHeapSize-XX:MaxHeapSize值。另外,參數(shù)-Dserver.port屬于系統(tǒng)參數(shù),使用jinfo -sysprops 13680就可以查看系統(tǒng)參數(shù)了。

5 堆內(nèi)存查看工具jmap

5.1 jmap說明

java應(yīng)用啟動(dòng)后,它在JVM中運(yùn)行,內(nèi)存是需要重點(diǎn)監(jiān)測的地方,jmap就是這樣的一個(gè)工具,它可以獲取運(yùn)行中的jvm的堆的快照,包括整體情況,堆占用情況的直方圖,dump出快照文件以便于離線分析等。官方文檔指出,這個(gè)命令在后續(xù)的版本中可能不再使用,當(dāng)前JDK8還是可以用的。

5.2 jmap使用

通過-help參數(shù)查看幫助,也可查閱jmap官方文檔說明https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jmap.html,幫助說明如下:

[root@test bin]# jmap -help
Usage:
    jmap [option] <pid>
        (to connect to running process)

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參數(shù)常用的是-heap,-histo-dump,結(jié)合示例java-monitor-example,說明如下:

  • 打印jvm內(nèi)存整體使用情況
[root@test bin]# jmap -heap 13680
Attaching to process ID 13680, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.51-b03

using thread-local object allocation.
Parallel GC with 2 thread(s)

Heap Configuration:
   MinHeapFreeRatio         = 0
   MaxHeapFreeRatio         = 100
   MaxHeapSize              = 134217728 (128.0MB)
   NewSize                  = 44564480 (42.5MB)
   MaxNewSize               = 44564480 (42.5MB)
   OldSize                  = 89653248 (85.5MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 0 (0.0MB)

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 31981568 (30.5MB)
   used     = 5306632 (5.060798645019531MB)
   free     = 26674936 (25.43920135498047MB)
   16.59278244268699% used
From Space:
   capacity = 6291456 (6.0MB)
   used     = 1081440 (1.031341552734375MB)
   free     = 5210016 (4.968658447265625MB)
   17.18902587890625% used
To Space:
   capacity = 6291456 (6.0MB)
   used     = 0 (0.0MB)
   free     = 6291456 (6.0MB)
   0.0% used
PS Old Generation
   capacity = 89653248 (85.5MB)
   used     = 16615680 (15.845947265625MB)
   free     = 73037568 (69.654052734375MB)
   18.533271655701753% used

18006 interned Strings occupying 2328928 bytes.

從以上信息,可以看出JVM中堆內(nèi)存當(dāng)前的使用情況,包括年輕代(Eden區(qū),From區(qū),To區(qū))和年老代。

  • 查看類名,對(duì)象數(shù)量,對(duì)象占用大小直方圖

[root@test bin]# jmap -histo:live 13680|more

 num     #instances         #bytes  class name
----------------------------------------------
   1:         36536        6462912  [C
   2:         35557         853368  java.lang.String
   3:          7456         826968  java.lang.Class
   4:         20105         643360  java.util.concurrent.ConcurrentHashMap$Node
   5:          1449         469024  [B
   6:          6951         399280  [Ljava.lang.Object;
   7:          9311         297952  java.util.HashMap$Node
   8:          3122         274736  java.lang.reflect.Method
   9:          2884         269112  [I
  10:          6448         257920  java.util.LinkedHashMap$Entry
  11:          2994         255160  [Ljava.util.HashMap$Node;
  12:         15249         243984  java.lang.Object

.....
.....

如上所示,使用-histo輸出包括序號(hào),實(shí)例數(shù),占用字節(jié)數(shù)和類名稱。具體說明如下:

  1. instances列:表示當(dāng)前類有多少個(gè)實(shí)例。
  2. bytes列:說明當(dāng)前類的實(shí)例總共占用了多少個(gè)字節(jié)
  3. class name列:表示的就是當(dāng)前類的名稱,class name 解讀:
  4. B代表byte
  5. C代表char
  6. D代表double
  7. F代表float
  8. I代表int
  9. J代表long
  10. Z代表boolean
  11. [代表數(shù)組,如[I相當(dāng)于int[]
  12. 對(duì)象用[L+類名表示
  • 把內(nèi)存情況dump內(nèi)存到本地文件

[root@test bin]# jmap -dump:file=./heap.hprof 13680

如上所示,會(huì)把堆情況寫入到當(dāng)前目錄的heap.hprof文件中,至于如何分析此文件,可以使用jhat,但一般實(shí)際開發(fā)中,很少使用jhat來直接對(duì)內(nèi)存dump文件進(jìn)行分析,因此不再對(duì)它進(jìn)行講述。更多的是使用工具MAT,以可視化的方式來查看,后續(xù)文章將會(huì)對(duì)MAT工具的使用進(jìn)行詳細(xì)講解。

6 線程棧查詢工具jstack

6.1 jstack說明

此命令打印指定Java應(yīng)用的線程堆棧,對(duì)于每個(gè)Java幀,將打印完整的類名,方法名,字節(jié)代碼索引(BCI)和行號(hào),可以用于檢測死鎖,線程停頓,進(jìn)程耗用cpu過高報(bào)警問題等排查。

6.2 jstack使用

使用-help參數(shù)查看幫助,也可查閱jstack官方文檔說明https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstack.html,幫助說明如下:


[root@test bin]# jstack -help
Usage:
    jstack [-l] <pid>
        (to connect to running process)
    jstack -F [-m] [-l] <pid>

Options:
    -F  強(qiáng)制dump線程堆棧信息. 用于進(jìn)程hung住, jstack <pid>命令沒有響應(yīng)的情況
    -m  同時(shí)打印java和本地(native)線程棧信息,m是mixed mode的簡寫
    -l  打印鎖的額外信息

結(jié)合示例java-monitor-example,可以打印線程信息(一般都會(huì)把打印的內(nèi)容寫入到文件然后再分析),如下:

  • 打印當(dāng)前線程堆棧信息
[root@test bin]# jstack 13680
2019-08-16 23:18:18
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.51-b03 mixed mode):
"http-nio-8083-Acceptor-0" #39 daemon prio=5 os_prio=0 tid=0x00007f7520698800 nid=0x359a runnable [0x00007f7508bb7000]
   java.lang.Thread.State: RUNNABLE
    at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)
    at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:422)
    at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:250)
    - locked <0x00000000f8c85380> (a java.lang.Object)
    at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:448)
    at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:70)
    at org.apache.tomcat.util.net.Acceptor.run(Acceptor.java:95)
    at java.lang.Thread.run(Thread.java:745)

6.3 線程dump分析

6.3.1 線程狀態(tài)

java線程棧使用jstackdump出來后,可以看到線程的狀態(tài),線程狀態(tài)一共分6種,可以參考官方文檔https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr034.html,下面是它的狀態(tài)說明:

  • NEW

線程已經(jīng)new出來創(chuàng)建了,但是還沒有啟動(dòng)(not yet started),jstack不會(huì)打印這個(gè)狀態(tài)的線程信息。

  • RUNNABLE

正在Java虛擬機(jī)下跑任務(wù)的線程的狀態(tài),但其實(shí)它是只是表示線程是可運(yùn)行的(ready)。對(duì)于單核的CPU,多個(gè)線程在同一時(shí)刻,只能運(yùn)行一個(gè)線程,其它的則需要等CPU的調(diào)度。

  • BLOCKED

線程處于阻塞狀態(tài),正在等待一個(gè)鎖,多個(gè)線程共用一個(gè)鎖,當(dāng)某線程正在使用這個(gè)鎖進(jìn)入某個(gè)synchronized同步方法塊或者方法,而此線程需要進(jìn)入這個(gè)同步代碼塊,也需要這個(gè)鎖,則導(dǎo)致本線程處于阻塞狀態(tài)。

  • WAITING

等待狀態(tài),處于等待狀態(tài)的線程是由于執(zhí)行了3個(gè)方法中的任意方法。 1. Object.wait方法,并且沒有使用timeout參數(shù); 2. Thread.join方法,沒有使用timeout參數(shù) 3. LockSupport.park方法。 處于waiting狀態(tài)的線程會(huì)等待另外一個(gè)線程處理特殊的行為。一個(gè)線程處于等待狀態(tài)(wait,通常是在等待其他線程完成某個(gè)操作(notify或者notifyAll)。注意,Object.wait()方法只能夠在同步代碼塊中調(diào)用。調(diào)用了wait()方法后,會(huì)釋放鎖。

  • TIMED_WAITING

線程等待指定的時(shí)間,對(duì)于以下方法的調(diào)用,可能會(huì)導(dǎo)致線程處于這個(gè)狀態(tài):1. Thread.sleep方法 2. Object.wait方法,帶有時(shí)間 3. Thread.join方法,帶有時(shí)間 4. LockSupport.parkNanos方法,帶有時(shí)間 5. LockSupport.parkUntil方法,帶有時(shí)間。注意,Thread.sleep方法調(diào)用后,它不會(huì)釋放鎖,仍然占用系統(tǒng)資源。

  • TERMINATED

線程中止的狀態(tài),這個(gè)線程已經(jīng)完整地執(zhí)行了它的任務(wù)。

從下面這張圖可以看出線程狀態(tài)的變化情況:

image

6.3.2 分析jstack后線程棧內(nèi)容

從前面使用jstack dump出來信息,我們需要知道以下幾個(gè)信息:

  • "http-nio-8083-Acceptor-0" #39:是線程的名字,因此,一般我們創(chuàng)建線程時(shí)需要設(shè)置自己可以辯識(shí)的名字。
  • daemon 表示線程是否是守護(hù)線程
  • prio 表示我們?yōu)榫€程設(shè)置的優(yōu)先級(jí)
  • os_prio 表示的對(duì)應(yīng)的操作系統(tǒng)線程的優(yōu)先級(jí),由于并不是所有的操作系統(tǒng)都支持線程優(yōu)先級(jí),所以可能會(huì)出現(xiàn)都置為0的情況
  • tid 線程的id
  • nid 線程對(duì)應(yīng)的操作系統(tǒng)本地線程id,每一個(gè)java線程都有一個(gè)對(duì)應(yīng)的操作系統(tǒng)線程,它是16進(jìn)制的,因此一般在操作系統(tǒng)中獲取到線程ID后,需要轉(zhuǎn)為16進(jìn)制,來對(duì)應(yīng)上。
  • java.lang.Thread.State: RUNNABLE 運(yùn)行狀態(tài),上面已經(jīng)介紹了線程的狀態(tài),若是WAITING狀態(tài),則括號(hào)中的內(nèi)容說明了導(dǎo)致等待的原因,如parking說明是因?yàn)檎{(diào)用了LockSupport.park方法導(dǎo)致等待。通常的堆棧信息中,都會(huì)有l(wèi)ock標(biāo)記,如- locked <0x00000000f8c85380> (a java.lang.Object)表示正在占用這個(gè)鎖。
  • 對(duì)于線程停頓,CPU占用等問題,可以重點(diǎn)看一下wait狀態(tài)的線程
  • 對(duì)于死鎖,在Dump出來的線程??煺湛梢灾苯訄?bào)告出Java級(jí)別的死鎖。

7 JVM統(tǒng)計(jì)數(shù)據(jù)工具jstat

7.1 jstat說明

jstatJVM Statistics Monitoring Tool,即JVM統(tǒng)計(jì)監(jiān)測工具,包括監(jiān)測類裝載、內(nèi)存、垃圾收集、JIT編譯等運(yùn)行數(shù)據(jù),在沒有圖形的服務(wù)器上,它是運(yùn)行期定位虛擬機(jī)性能問題的首選工具。

7.2 jstat使用

使用-help參數(shù)查看幫助,也可查閱jstat官方文檔說明https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html,幫助說明如下:

[root@test bin]# jstat -help
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
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.

以上所示,vmid、interval、count分別是進(jìn)程號(hào),打印間隔時(shí)間(s或ms),打印次數(shù),其中option參數(shù)主要是以下(也可以使用命令jstat -option查看):

  • -class 統(tǒng)計(jì)class loader行為信息 ,如總共加載了多少個(gè)類
  • -compile 統(tǒng)計(jì)HotSpot Just-in-Time編譯器的行為
  • -gc 統(tǒng)計(jì)jdk gc時(shí)heap信息
  • -gccapacity 統(tǒng)計(jì)不同的generations相應(yīng)的heap容量情況
  • -gccause 統(tǒng)計(jì)gc的情況,(同-gcutil)和引起gc的事件
  • -gcnew 統(tǒng)計(jì)gc時(shí),新生代的情況
  • -gcnewcapacity 統(tǒng)計(jì)gc時(shí),新生代heap容量
  • -gcold 統(tǒng)計(jì)gc時(shí),老年區(qū)的情況
  • -gcoldcapacity 統(tǒng)計(jì)gc時(shí),老年區(qū)heap容量
  • -gcpermcapacity 統(tǒng)計(jì)gc時(shí),permanent區(qū)heap容量
  • -gcutil 統(tǒng)計(jì)gc時(shí),heap情況
  • -printcompilation hotspot編譯方法統(tǒng)計(jì)

一般我們使用-class-gc,-gccause-gcutil比較多,主要用于來分析類和堆使用情況及gc情況。

7.3 監(jiān)測JVM的GC情況

以上述的示例工程java-monitor-example為例,里面包含了一個(gè)函數(shù)來測試內(nèi)存溢出(使用一個(gè)數(shù)組,循環(huán)創(chuàng)建對(duì)象,直到內(nèi)存溢出)。使用jstat -gc 13680 1000即每秒監(jiān)測一次,調(diào)用/monitor/user/oom接口后,即看到堆和GC變化情況。為方便查看,我把輸出放到sublime中顯示,如下所示:

image

日志輸出OOM報(bào)錯(cuò):

image

以上輸出的內(nèi)容,每列的說明如下:

  • S0C 當(dāng)前年輕代中第一個(gè)survivor(s0)的總?cè)萘?(KB).
  • S1C 當(dāng)前年輕代中第一個(gè)survivor(s1)的總?cè)萘?(KB).
  • S0U s0已使用的容量 (KB).
  • S1U s1已使用的容量 (KB).
  • EC 當(dāng)前年輕代中eden區(qū)總?cè)萘?(KB).
  • EU eden區(qū)已經(jīng)使用的容量 (KB).
  • OC 年老代的容量總?cè)萘?(KB).
  • OU 年老代已使用容量(KB).
  • MC 當(dāng)前 Metaspace總?cè)萘?KB).
  • MU 當(dāng)前 Metaspace已使用容量 (KB).
  • CCSC Compressed class容量大小
  • CCSU Compressed class已使用容量
  • YGC 從應(yīng)用啟動(dòng)時(shí)到現(xiàn)在,年輕代young generation 發(fā)生GC Events的總次數(shù).
  • YGCT 從應(yīng)用啟動(dòng)時(shí)到現(xiàn)在, 年輕代Young generation 垃圾回收的總耗時(shí).
  • FGC 從應(yīng)用啟動(dòng)時(shí)到現(xiàn)在, full GC事件總次數(shù).
  • FGCT 從應(yīng)用啟動(dòng)時(shí)到現(xiàn)在, Full sc總耗時(shí).GCT 從應(yīng)用啟動(dòng)時(shí)到現(xiàn)在, 垃圾回收總時(shí)間. - GCT GCT=YGCT+FGCT

從以上輸出第6行可以看出,ECEUOCOU表示年輕代、年老代的內(nèi)存都已經(jīng)用完(與容量數(shù)值相等),發(fā)生OOM。這時(shí),則需要采取措施,增大內(nèi)存(-Xmx參數(shù))或者找到導(dǎo)致OOM的代碼進(jìn)行修改。

8 總結(jié)

針對(duì)java應(yīng)用的監(jiān)測,本文對(duì)jdk提供自身提供的命令行工具進(jìn)行了說明和使用的介紹,完整的描述了查看java應(yīng)用進(jìn)程,查看啟動(dòng)參數(shù),查看內(nèi)存情況,查看線程情況,查看內(nèi)存統(tǒng)計(jì)情況等,主要是jps,jinfojmap,jstack,jstat5個(gè)工具,并結(jié)合實(shí)例,希望學(xué)習(xí)java開發(fā)人員都能掌握這些技術(shù),在監(jiān)測java應(yīng)用時(shí),可以從容面對(duì)如OOM,CPU高,線程停頓等問題。

參考資料

相關(guān)閱讀

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

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

  • JDK 命令行工具 主要介紹 jps、jstat、jinfo、jmap、jhat、jstatc 等幾個(gè)JDK命令行...
    花神子閱讀 860評(píng)論 0 1
  • 作者:一字馬胡 轉(zhuǎn)載標(biāo)志 【2017-11-12】 更新日志 日期更新內(nèi)容備注 2017-11-12新建文章初版 ...
    beneke閱讀 2,323評(píng)論 0 7
  • JDK 監(jiān)控和故障處理工具總結(jié) JDK 命令行工具 這些命令在 JDK 安裝目錄下的 bin 目錄下: jps (...
    綠葉悠閱讀 356評(píng)論 0 0
  • JDK 命令行工具 這些命令在 JDK 安裝目錄下的 bin 目錄下: jps (JVM Process Stat...
    willcoder閱讀 361評(píng)論 0 1
  • 白川不后悔認(rèn)識(shí)了墨宸,所以對(duì)墨宸,他放下了防備,打開封閉的心門,讓他走了進(jìn)來,留下著墨宸踏足的印記。 白川知道...
    祈滄閱讀 295評(píng)論 0 0

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