JVM問題排查之常用命令

開篇

要想排查jvm的線上問題,必先熟悉常用命令。
主要有下列這些:
jvm相關的命令:jinfo jmap jstat jstack jps
linux系統相關命令:top ps print diff free netstat wc
文檔查看相關命令:less more vi vim
高級命令:sed awk grep egrep sort head

熟悉上面這些命令才能在生產環境排查問題時遊刃有餘,當然還需要經驗的積累,才能變成找問題工程師。

linux相關

查看系統運行的最大句柄數 open files

[root@4mfb6 root]# ulimit -a
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 256766
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 655350
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192

查看當前系統運行的句柄數
1是pid

[root@4mfb6 root]# ll /proc/1/fd | wc -l
335

查看當前系統運行的線程數

[root@4mfb6 root]# ll /proc/1/task/ | wc -l
630```

# JVM相關命令
## jps
查看當前系統的java進程id和進程名
> jps
```java
[root@localhost ~]$ jps
21381 BrokerStartup
24696 Jps
20668 NamesrvStartup

jinfo

查看jvm的所有運行時參數(相當於 jinfo -sysprops -flags pid

jinfo pid;

查看某個參數的值

jinfo -flag name pid

[root@localhost ~]$ jinfo -flag MaxMetaspaceSize 17246
-XX:MaxMetaspaceSize=335544320

生效或者失效某個參數

jinfo -flag [+|-] name pid

[root@localhost ~]$ jinfo -flag -PrintGCTimeStamps 17246
[root@localhost ~]$ jinfo -flag +PrintGCTimeStamps 17246

運行時設置jvm的參數值(我試了幾個參數都不能被修改,放棄)

jinfo -flag MaxMetaspaceSize =1000000000 pid

[root@localhost ~]$ jinfo -flag MaxMetaspaceSize=1000000000 17246
Exception in thread "main" com.sun.tools.attach.AttachOperationFailedException: flag 'MaxMetaspaceSize' cannot be changed

        at sun.tools.attach.LinuxVirtualMachine.execute(LinuxVirtualMachine.java:229)
        
[root@localhost ~]$ jinfo -flag MaxHeapSize=5000000000 17246
Exception in thread "main" com.sun.tools.attach.AttachOperationFailedException: flag 'MaxHeapSize' cannot be changed

        at sun.tools.attach.LinuxVirtualMachine.execute(LinuxVirtualMachine.java:229)
       
[root@localhost ~]$ jinfo -flag NumberOfGCLogFiles=50 17246
Exception in thread "main" com.sun.tools.attach.AttachOperationFailedException: flag 'NumberOfGCLogFiles' cannot be changed

        at sun.tools.attach.LinuxVirtualMachine.execute(LinuxVirtualMachine.java:229)

只查看jvm相關的參數

jinfo -flags pid

[root@localhost ~]$ jinfo -flags 17246
Attaching to process ID 17246, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.112-b15
Non-default VM flags: -XX:CICompilerCount=2 -XX:+CMSClassUnloadingEnabled -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:GCLogFileSize=31457280 -XX:InitialHeapSize=4294967296 -XX:MaxHeapSize=4294967296 -XX:MaxMetaspaceSize=335544320 -XX:MaxNewSize=2147483648 -XX:MetaspaceSize=134217728 -XX:MinHeapDeltaBytes=196608 -XX:NewSize=2147483648 -XX:NumberOfGCLogFiles=5 -XX:OldPLABSize=16 -XX:OldSize=2147483648 -XX:-OmitStackTraceInFastThrow -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:SoftRefLRUPolicyMSPerMB=0 -XX:SurvivorRatio=8 -XX:+UseCMSCompactAtFullCollection -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:+UseFastUnorderedTimeStamps -XX:+UseGCLogFileRotation -XX:-UseLargePages -XX:-UseParNewGC
Command line:  -Xms4g -Xmx4g -Xmn2g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+CMSClassUnloadingEnabled -XX:SurvivorRatio=8 -XX:-UseParNewGC -verbose:gc -Xloggc:/dev/shm/rmq_srv_gc_%p_%t.log -XX:+PrintGCDetails -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m -XX:-OmitStackTraceInFastThrow -XX:-UseLargePages -Djava.ext.dirs=/home/root/jdk1.8.0_112/jre/lib/ext:/home/root/kafka_2.11-1.0.0/bin/rocketmq-all-4.7.0-bin-release/bin/../lib

查看系統的參數

jinfo -sysprops pid

[root@localhost ~]$ jinfo -sysprops 17246
Attaching to process ID 17246, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.112-b15
java.runtime.name = Java(TM) SE Runtime Environment
java.vm.version = 25.112-b15
sun.boot.library.path = /home/root/jdk1.8.0_112/jre/lib/amd64
rocketmq.remoting.version = 353
java.vendor.url = http://java.oracle.com/
java.vm.vendor = Oracle Corporation
path.separator = :
file.encoding.pkg = sun.io
java.vm.name = Java HotSpot(TM) 64-Bit Server VM
sun.os.patch.level = unknown
...

jstack

查看當前jvm主進程的所有線程 。

jstack pid

[root@localhost ~]$ jstack 17246
2020-05-30 23:11:59
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.112-b15 mixed mode):

"Attach Listener" #28 daemon prio=9 os_prio=0 tid=0x00007f6930001000 nid=0x462f waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE
  • Attach Listener:線程名
  • #28:看着像是線程的編號,第一個啓動的是1
  • daemon:表示是jvm的守護進程,當主進程關閉,jvm會整個關閉。
  • prio=9:是java的線程優先級,thread類的一個屬性
  • os_prio=0:是操作系統的線程優先級
  • tid=0x00007f6930001000:是java線程的id,thread類的一個屬性。
  • nid=0x462f:是操作系統級別的線程id,16進制。(linux下16進制和10進制互轉命令,print %d 0x462f; print %x 17246
  • waiting on condition [0x0000000000000000]:具體是等待在哪裏
  • java.lang.Thread.State: RUNNABLE:線程的狀態。全部狀態在Thread的State類(NEW、RUNNING、BLOCKED、WAITING、TIME_WAITING、TERMINATED)中。

查看當前jvm主進程的所有線程 。附加打印本地方法棧

jstack -m pid

----------------- 17967 -----------------
0x0000003d02c0eb2d      __libc_accept + 0x2d
0x00007f696cbf8bae      _ZN14AttachListener7dequeueEv + 0x9e
0x00007f696cbf7aba      _ZL28attach_listener_thread_entryP10JavaThreadP6Thread + 0x19a
0x00007f696d3505f3      _ZN10JavaThread17thread_main_innerEv + 0x103
0x00007f696d35073c      _ZN10JavaThread3runEv + 0x11c
0x00007f696d201138      _ZL10java_startP6Thread + 0x108

查看當前jvm主進程的所有線程 。附加打印具體鎖信息

jstack -l pid

"Attach Listener" #28 daemon prio=9 os_prio=0 tid=0x00007f6930001000 nid=0x462f waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

jstat

可以看到jstat的選項較多。但是大的是三塊gc、class、compiler

[root@localhost ~]$ jstat -options
-class
-compiler
-gc
-gccapacity
-gccause
-gcmetacapacity
-gcnew
-gcnewcapacity
-gcold
-gcoldcapacity
-gcutil
-printcompilation

查看jvm加載的class信息

jstat -class pid

[root@localhost ~]$ jstat -class 17246
Loaded  Bytes  Unloaded  Bytes     Time
  2683  5201.9        0     0.0       1.21
  • Loaded :加載class的個數
  • Bytes:加載class的字節數
  • Unloaded :卸載class的個數
  • Bytes:卸載class的字節數
  • Time:加載和卸載的總耗時

查看java類編譯器編譯的信息 (感覺作用不大,除非可以知道JIT的編譯情況)

jstat -compiler pid

[root@localhost ~]$ jstat -compiler 17246
Compiled Failed Invalid   Time   FailedType FailedMethod
    1271      0       0     1.73          0

查看gc的情況,堆內存以字節的形式展示

jstat -gc pid [interval] [count]

查看gc的情況,堆內存以百分比的形式展示

jstat -gcutil pid [interval] [count]

查看gc的原因

jstat -gccause pid [interval] [count]

sh-4.2# jstat -gccause 1 1000 50                                                                                                                                                                                 
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT    LGCC                 GCC                                                                                                                                                                                                              
 60.94   0.00  99.09  49.62  95.21  92.84    706   74.757     0    0.000   74.757 Allocation Failure   No GC                                                                                                       
 60.94   0.00  99.98  49.62  95.21  92.84    706   74.757     0    0.000   74.757 Allocation Failure   No GC                                                                                                       
  0.00  67.19   1.84  49.64  95.21  92.84    707   74.866     0    0.000   74.866 Allocation Failure   No GC                                                                                                       
  0.00  67.19   1.90  49.64  95.21  92.84    707   74.866     0    0.000   74.866 Allocation Failure   No GC                                                                                                       

jmap

一共有-heap、-histo、-dump、 -clsstats、finalizerinfo幾種選項,而且前四個都比較重要

類似linux的pmap命令

jmap pid

[root@localhost ~]$ jmap 21381
Attaching to process ID 21381, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.112-b15
0x0000000000400000      7K      /home/root/jdk1.8.0_112/bin/java
0x0000003d02400000      157K    /lib64/ld-2.12.so
0x0000003d02800000      1885K   /lib64/libc-2.12.so
0x0000003d02c00000      143K    /lib64/libpthread-2.12.so

打印jvm堆的詳細信息,包括各分代的初始,已使用,空閒的內存大小。以及關於堆的jvm參數值

jmap -heap pid

[root@localhost ~]$ jmap -heap 21381
Attaching to process ID 21381, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.112-b15

using thread-local object allocation.
Garbage-First (G1) GC with 2 thread(s)

Heap Configuration:
   MinHeapFreeRatio         = 40
   MaxHeapFreeRatio         = 70
   MaxHeapSize              = 1073741824 (1024.0MB)
   NewSize                  = 1363144 (1.2999954223632812MB)
   MaxNewSize               = 637534208 (608.0MB)
   OldSize                  = 5452592 (5.1999969482421875MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 16777216 (16.0MB)

Heap Usage:
G1 Heap:
   regions  = 64
   capacity = 1073741824 (1024.0MB)
   used     = 27190200 (25.93059539794922MB)
   free     = 1046551624 (998.0694046020508MB)
   2.5322847068309784% used
G1 Young Generation:
Eden Space:
   regions  = 0
   capacity = 50331648 (48.0MB)
   used     = 0 (0.0MB)
   free     = 50331648 (48.0MB)
   0.0% used
Survivor Space:
   regions  = 1
   capacity = 16777216 (16.0MB)
   used     = 16777216 (16.0MB)
   free     = 0 (0.0MB)
   100.0% used
G1 Old Generation:
   regions  = 2
   capacity = 1006632960 (960.0MB)
   used     = 10412984 (9.930595397949219MB)
   free     = 996219976 (950.0694046020508MB)
   1.0344370206197102% used

7807 interned Strings occupying 701616 bytes.

查看當前(存活)堆中對象的分佈情況。常常用來查找內存泄漏問題

jmap -histo[:live] pid

[root@localhost ~]$ jmap -histo 21381 | head -n 15

 num     #instances         #bytes  class name
----------------------------------------------
   1:         16152       21883608  [B
   2:          2904        8052288  [I
   3:         79506        4452336  org.apache.rocketmq.store.schedule.ScheduleMessageService$DeliverDelayedMessageTimerTask
   4:         38040        3697960  [C
   5:         93669        2997408  java.util.concurrent.locks.AbstractQueuedSynchronizer$Node
   6:         82557        1320912  java.lang.Object
   7:         31793         763032  java.lang.String
   8:          3293         377312  java.lang.Class
   9:          5238         339224  [Ljava.lang.Object;
  10:          4239         229944  [Ljava.lang.String;
  11:          4366         209568  java.util.HashMap
  12:          6418         154032  java.util.concurrent.CopyOnWriteArrayList$COWIterator
  • num:編號,默認字節數從大到小排序
  • #instances:對象數
  • #bytes:類實例化對象所佔的內存大小
  • class name:類名稱

查看類加載的情況

jmap -clstats pid

[root@localhost ~]$ jmap -clstats 21381
class_loader    classes bytes   parent_loader   alive?  type
<bootstrap>     1793    3250520   null          live    <internal>
0x00000000fc000000      1       880     0x00000000c02779f8      dead    sun/reflect/DelegatingClassLoader@0x0000000100009df8
0x00000000fc000380      1       1471      null          dead    sun/reflect/DelegatingClassLoader@0x0000000100009df8

查看當前的finalize隊列中的個數

jmap -finalizerinfo pid

[root@localhost ~]$ jmap -finalizerinfo 21381
Attaching to process ID 21381, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.112-b15
Number of objects pending for finalization: 0

dump當前jvm的內存堆。dump下來的文件可以使用MemoryAnalyzer分析。也可以使用jvisualvm來分析。(注意此操作可能導致jvm進程掛掉

jmap -dump:format=b,file=filename pid

[root@localhost ~]$ jmap -dump:format=b,file=20200531.hp 21381
Dumping heap to /home/root/20200531.hp ...
Heap dump file created
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章