jvm性能調常用工具Jinfo Jstat Jmap Jstack jvisualvm

jinfo使用

可以查看java的系統參數

可以查看某個JVM的參數

可以調整某個JVM的參數

 查看jvm的參數

λ jps
9920 jar
3524
1512 Launcher
10028 Jps
λ jinfo -flags 9920
Attaching to process ID 9920, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.171-b11
Non-default VM flags: -XX:CICompilerCount=3 -XX:InitialHeapSize=132120576 -XX:MaxHeapSize=2105540608 -XX:MaxNewSize=701497344 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=44040192 -XX:OldSize=88080384 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
Command line:

查看java系統參數

λ jinfo -sysprops 9920
Attaching to process ID 9920, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.171-b11
java.runtime.name = Java(TM) SE Runtime Environment
java.vm.version = 25.171-b11
sun.boot.library.path = C:\Program Files\Java\jre1.8.0_171\bin
java.protocol.handler.pkgs = org.springframework.boot.loader
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 = Service Pack 1
sun.java.launcher = SUN_STANDARD
user.script =
user.country = CN
。。。。

Jstat

jstat命令可以查看堆內存各部分的使用量,以及加載類的數量。命令的格式如下:

jstat [-命令選項] [vmid] [間隔時間/毫秒] [查詢次數]

注意:使用的jdk版本是jdk8.

 類加載統計:

λ jstat.exe -class 9920
Loaded  Bytes  Unloaded  Bytes     Time
 10016 17802.1        0     0.0      16.63
  1. Loaded:加載class的數量
  2. Bytes:所佔用空間大小
  3. Unloaded:未加載數量
  4. Bytes:未加載佔用空間
  5. Time:時間

垃圾回收統計

λ jstat.exe -gc 9920
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
11776.0 10752.0  0.0   8965.3 656384.0 162951.3  91136.0    31814.1   48896.0 47920.8 6400.0 6203.8     15    0.305   2      0.165    0.470

 

λ jjstat.exe -gc 9920 1000 5
#也可以指定打印的間隔和次數,每1秒中打印一次,共打印5次
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
512.0  512.0  128.0   0.0   30208.0  23473.1   91136.0    37991.3   51072.0 50049.2 6784.0 6504.7    262    1.565   2      0.165    1.730
512.0  512.0   0.0   128.0  30208.0   4820.6   91136.0    37991.3   51072.0 50049.2 6784.0 6504.7    263    1.567   2      0.165    1.732
512.0  512.0   0.0   128.0  30208.0  15649.0   91136.0    37991.3   51072.0 50049.2 6784.0 6504.7    263    1.567   2      0.165    1.732
512.0  512.0   0.0   128.0  30208.0  27050.5   91136.0    37991.3   51072.0 50049.2 6784.0 6504.7    263    1.567   2      0.165    1.732
512.0  512.0  128.0   0.0   30208.0   7565.2   91136.0    37991.3   51072.0 50049.2 6784.0 6504.7    264    1.569   2      0.165    1.734
  1. S0C:第一個倖存區的大小 (Kb)
  2. S1C:第二個倖存區的大小 (Kb)
  3. S0U:第一個倖存區的使用大小 (Kb)
  4. S1U:第二個倖存區的使用大小 (Kb)
  5. EC:伊甸園區的大小 (Kb)
  6. EU:伊甸園區的使用大小 (Kb)
  7. OC:老年代大小 (Kb)
  8. OU:老年代使用大小 (Kb)
  9. MC:方法區大小(元空間) (Kb)
  10. MU:方法區使用大小 (Kb)
  11. CCSC:壓縮類空間大小 (Kb)
  12. CCSU:壓縮類空間使用大小
  13. YGC:年輕代垃圾回收次數
  14. YGCT:年輕代垃圾回收消耗時間
  15. FGC:老年代垃圾回收次數
  16. FGCT:老年代垃圾回收消耗時間
  17. GCT:垃圾回收消耗總時間

堆內存統計: 

λ jstat.exe -gccapacity 9920
 NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC         OC       MCMN     MCMX      MC     CCSMN    CCSMX     CCSC    YGC    FGC
 43008.0 685056.0 685056.0 11776.0 10752.0 656384.0    86016.0  1371136.0    91136.0    91136.0      0.0 1091584.0  48896.0      0.0 1048576.0   6400.0     15     2
  1. NGCMN:新生代最小容量
  2. NGCMX:新生代最大容量
  3. NGC:當前新生代容量
  4. S0C:第一個倖存區大小
  5. S1C:第二個倖存區的大小
  6. EC:伊甸園區的大小
  7. OGCMN:老年代最小容量
  8. OGCMX:老年代最大容量
  9. OGC:當前老年代大小
  10. OC:當前老年代大小
  11. MCMN:最小元數據容量
  12. MCMX:最大元數據容量
  13. MC:當前元數據空間大小
  14. CCSMN:最小壓縮類空間大小
  15. CCSMX:最大壓縮類空間大小
  16. CCSC:當前壓縮類空間大小
  17. YGC:年輕代gc次數
  18. FGC:老年代GC次數

新生代內存統計

λ jstat.exe -gcnew 9920
 S0C    S1C    S0U    S1U   TT MTT  DSS      EC       EU     YGC     YGCT
11776.0 10752.0    0.0 8965.3  2  15 11776.0 656384.0 169515.4     15    0.305
  1. NGCMN:新生代最小容量
  2. NGCMX:新生代最大容量
  3. NGC:當前新生代容量
  4. S0CMX:最大幸存1區大小
  5. S0C:當前倖存1區大小
  6. S1CMX:最大幸存2區大小
  7. S1C:當前倖存2區大小
  8. ECMX:最大伊甸園區大小
  9. EC:當前伊甸園區大小
  10. YGC:年輕代垃圾回收次數
  11. FGC:老年代回收次數

 老年代垃圾回收統計

λ jstat.exe -gcold 9920
   MC       MU      CCSC     CCSU       OC          OU       YGC    FGC    FGCT     GCT
 48896.0  47920.8   6400.0   6203.8     91136.0     31814.1     15     2    0.165    0.470
  1. MC:方法區大小
  2. MU:方法區使用大小
  3. CCSC:壓縮類空間大小
  4. CCSU:壓縮類空間使用大小
  5. OC:老年代大小
  6. OU:老年代使用大小
  7. YGC:年輕代垃圾回收次數
  8. FGC:老年代垃圾回收次數
  9. FGCT:老年代垃圾回收消耗時間
  10. GCT:垃圾回收消耗總時間

老年代內存統計 

λ jstat.exe -gcoldcapacity 9920
   OGCMN       OGCMX        OGC         OC       YGC   FGC    FGCT     GCT
    86016.0   1371136.0     91136.0     91136.0    15     2    0.165    0.470
  1. OGCMN:老年代最小容量
  2. OGCMX:老年代最大容量
  3. OGC:當前老年代大小
  4. OC:老年代大小
  5. YGC:年輕代垃圾回收次數
  6. FGC:老年代垃圾回收次數
  7. FGCT:老年代垃圾回收消耗時間
  8. GCT:垃圾回收消耗總時間

元數據空間統計

λ jstat.exe -gcmetacapacity 9920
   MCMN       MCMX        MC       CCSMN      CCSMX       CCSC     YGC   FGC    FGCT     GCT
       0.0  1091584.0    48896.0        0.0  1048576.0     6400.0    15     2    0.165    0.470
  1. MCMN:最小元數據容量
  2. MCMX:最大元數據容量
  3. MC:當前元數據空間大小
  4. CCSMN:最小壓縮類空間大小
  5. CCSMX:最大壓縮類空間大小
  6. CCSC:當前壓縮類空間大小
  7. YGC:年輕代垃圾回收次數
  8. FGC:老年代垃圾回收次數
  9. FGCT:老年代垃圾回收消耗時間
  10. GCT:垃圾回收消耗總時間

gc工具gcutil參數

λ jstat.exe -gcutil 9920
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
  0.00  83.38  26.33  34.91  98.01  96.93     15    0.305     2    0.165    0.470
  1. S0:倖存1區當前使用比例
  2. S1:倖存2區當前使用比例
  3. E:伊甸園區使用比例
  4. O:老年代使用比例
  5. M:元數據區使用比例
  6. CCS:壓縮使用比例
  7. YGC:年輕代垃圾回收次數
  8. FGC:老年代垃圾回收次數
  9. FGCT:老年代垃圾回收消耗時間
  10. GCT:垃圾回收消耗總時間 

jmap 

前面通過jstat可以對jvm堆的內存進行統計分析,而jmap可以獲取到更加詳細的內容,
如:內存使用情況的彙總、對內存溢出的定位與分析

堆信息:

λ jmap.exe -heap 9920                                
Attaching to process ID 9920, please wait...         
Debugger attached successfully.                      
Server compiler detected.                            
JVM version is 25.171-b11                            
                                                     
using thread-local object allocation.                
Parallel GC with 4 thread(s)                         
                                                     
Heap Configuration:                                  
   MinHeapFreeRatio         = 0                      
   MaxHeapFreeRatio         = 100                    
   MaxHeapSize              = 2105540608 (2008.0MB)  
   NewSize                  = 44040192 (42.0MB)      
   MaxNewSize               = 701497344 (669.0MB)    
   OldSize                  = 88080384 (84.0MB)      
   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 = 672137216 (641.0MB)                    
   used     = 176945008 (168.74790954589844MB)       
   free     = 495192208 (472.25209045410156MB)       
   26.325726918236885% used                          
From Space:                                          
   capacity = 11010048 (10.5MB)                      
   used     = 9180504 (8.755210876464844MB)          
   free     = 1829544 (1.7447891235351562MB)         
   83.38296072823661% used                           
To Space:                                            
   capacity = 12058624 (11.5MB)                      
   used     = 0 (0.0MB)                              
   free     = 12058624 (11.5MB)                      
   0.0% used                                         
PS Old Generation                                    
   capacity = 93323264 (89.0MB)                      
   used     = 32577656 (31.06847381591797MB)         
   free     = 60745608 (57.93152618408203MB)         
   34.90839754597525% used                           
                                                     
25513 interned Strings occupying 3131664 bytes.      

 查看內存中對象數量及大小

#查看所有對象,包括活躍以及非活躍的
jmap ‐histo <pid> | more
#查看活躍對象
jmap ‐histo:live <pid> | more'
λ jmap.exe -histo:live 9920 | more

 num     #instances         #bytes  class name
----------------------------------------------
   1:         66633        8976600  [C
   2:         64870        1556880  java.lang.String
   3:         40185        1285920  java.util.concurrent.ConcurrentHashMap$Node
   4:         10604        1178176  java.lang.Class
   5:          8574         754512  java.lang.reflect.Method
   6:          3987         734032  [B
   7:         17124         684960  java.util.LinkedHashMap$Entry
   8:          5074         684432  [I
   9:          7759         550680  [Ljava.util.HashMap$Node;
  10:          9423         527688  java.util.LinkedHashMap
  11:          9325         518128  [Ljava.lang.Object;
  12:           260         502688  [Ljava.util.concurrent.ConcurrentHashMap$Node;
  13:         25660         410560  java.lang.Object
  14:         12815         410080  java.util.HashMap$Node
  15:          3754         150160  java.lang.ref.SoftReference
  16:          1555         149280  org.springframework.beans.GenericTypeAwarePropertyDescriptor
  17:          4567         146144  java.lang.ref.WeakReference

某測試環境發現部署的java進程(pid=1)經常full GC,長期內存佔用很高,疑似內存泄漏,現在想要確定是哪些類的實例佔用內存較多,那麼應該用下列選項中的那個命令

./jdk1.8.0_151/bin/jmap -histo 1

[service@usg-smn-191130100-8546f8ccd9-kfh6w usg]$ ./jdk1.8.0_151/bin/jmap -histo 1
Picked up JAVA_TOOL_OPTIONS: -javaagent:/paas-apm/collectors/pinpoint/pinpoint-bootstrap.jar -Dpinpoint.config=/paas-apm/collectors/pinpoint/pinpoint.config -Duser.stemming.config=/paas-apm/collectors/pinpoint/userStemming.config

 num     #instances         #bytes  class name
----------------------------------------------
   1:       2296244      231628904  [C
   2:        416554       53976048  [B
   3:          6283       37337624  [J
   4:       1360072       32641728  java.lang.String
   5:         96883       18168224  [I
   6:        253392       16217088  java.net.URL
   7:        332371       15953808  java.util.HashMap
   8:        260721       13617384  [Ljava.util.HashMap$Node;
   9:        218684       12189896  [Ljava.lang.Object;
  10:        257915        8253280  java.util.concurrent.locks.AbstractQueuedSynchronizer$Node
  11:        244856        7835392  org.springframework.boot.loader.jar.StringSequence
  12:        168575        6743000  java.util.LinkedHashMap$Entry
  13:        244856        5876544 
#對象說明
B byte
C char
D double
F float
I int
J long
Z boolean
[ 數組,如[I表示int[]
[L+類名 其他對象
  1. num:序號
  2. instances:實例數量
  3. bytes:佔用空間大小
  4. class name:類名稱

 

堆內存dump

有些時候我們需要將jvm當前內存中的情況dump到文件中,然後對它進行分析,jmap也
是支持dump到文件中的

#用法:
jmap ‐dump:format=b,file=dumpFileName <pid>
#示例
jmap ‐dump:format=b,file=/tmp/dump.dat 6219
D:\
λ jmap.exe -dump:format=b,file=eureka.hprof 9920
Dumping heap to D:\eureka.hprof ...
Heap dump file created

也可以設置內存溢出自動導出dump文件(內存很大的時候,可能會導不出來)

  1. -XX:+HeapDumpOnOutOfMemoryError
  2. -XX:HeapDumpPath=./   (路徑)

 

jstack的使用:

有些時候我們需要查看下jvm中的線程執行情況,比如,發現服務器的CPU的負載突然增
高了、出現了死鎖、死循環等,我們該如何分析呢?
由於程序是正常運行的,沒有任何的輸出,從日誌方面也看不出什麼問題,所以就需要
看下jvm的內部線程的執行情況,然後再進行分析查找出原因。
這個時候,就需要藉助於jstack命令了,jstack的作用是將正在運行的jvm的線程情況進
行快照,並且打印出來

#用法:jstack <pid>

D:\IntelIJWorkSpace\jvm>jps
1264 Jps
3524
1512 Launcher
3516 DeadLockTest

D:\IntelIJWorkSpace\jvm>jstack 3516
2020-06-27 16:10:02
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.171-b11 mixed mode):

"DestroyJavaVM" #13 prio=5 os_prio=0 tid=0x00000000020e9000 nid=0x17ec waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Thread-1" #12 prio=5 os_prio=0 tid=0x00000000594c7800 nid=0xa54 waiting for monitor entry [0x000000005941f000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at DeadLockTest.lambda$main$1(DeadLockTest.java:32)
        - waiting to lock <0x00000000d648e630> (a java.lang.Object)
        - locked <0x00000000d648e640> (a java.lang.Object)
        at DeadLockTest$$Lambda$2/1831932724.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:748)

"Thread-0" #11 prio=5 os_prio=0 tid=0x00000000594c2000 nid=0x1864 waiting for monitor entry [0x0000000059dbf000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at DeadLockTest.lambda$main$0(DeadLockTest.java:19)
        - waiting to lock <0x00000000d648e640> (a java.lang.Object)
        - locked <0x00000000d648e630> (a java.lang.Object)
        at DeadLockTest$$Lambda$1/990368553.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:748)

"Service Thread" #10 daemon prio=9 os_prio=0 tid=0x0000000058559800 nid=0x668 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C1 CompilerThread2" #9 daemon prio=9 os_prio=2 tid=0x000000005854e800 nid=0x18bc waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" #8 daemon prio=9 os_prio=2 tid=0x000000005853d000 nid=0x1c0c waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #7 daemon prio=9 os_prio=2 tid=0x000000005853c800 nid=0xf90 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Monitor Ctrl-Break" #6 daemon prio=5 os_prio=0 tid=0x0000000058539800 nid=0x1860 runnable [0x00000000589fe000]
   java.lang.Thread.State: RUNNABLE
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
        at java.net.SocketInputStream.read(SocketInputStream.java:171)
        at java.net.SocketInputStream.read(SocketInputStream.java:141)
        at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
        at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
        at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
        - locked <0x00000000d652cb40> (a java.io.InputStreamReader)
        at java.io.InputStreamReader.read(InputStreamReader.java:184)
        at java.io.BufferedReader.fill(BufferedReader.java:161)
        at java.io.BufferedReader.readLine(BufferedReader.java:324)
        - locked <0x00000000d652cb40> (a java.io.InputStreamReader)
        at java.io.BufferedReader.readLine(BufferedReader.java:389)
        at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64)

"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x00000000584e8800 nid=0x188c waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x00000000572c0000 nid=0x1d10 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x00000000572a5800 nid=0x19c0 in Object.wait() [0x00000000584df000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000000d6308ed0> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
        - locked <0x00000000d6308ed0> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:212)

"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x0000000057264000 nid=0x19bc in Object.wait() [0x000000005819f000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000000d6306bf8> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Object.java:502)
        at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
        - locked <0x00000000d6306bf8> (a java.lang.ref.Reference$Lock)
        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

"VM Thread" os_prio=2 tid=0x000000005725c800 nid=0x1a50 runnable

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00000000020fe000 nid=0x19cc runnable

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00000000020ff800 nid=0x1b34 runnable

"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x0000000002101000 nid=0x1a4c runnable

"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x0000000002102800 nid=0x12e0 runnable

"VM Periodic Task Thread" os_prio=2 tid=0x0000000058624000 nid=0xd58 waiting on condition

JNI global references: 317


Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock monitor 0x00000000572b1148 (object 0x00000000d648e630, a java.lang.Object),
  which is held by "Thread-0"
"Thread-0":
  waiting to lock monitor 0x00000000572ae758 (object 0x00000000d648e640, a java.lang.Object),
  which is held by "Thread-1"

Java stack information for the threads listed above:
===================================================
"Thread-1":
        at DeadLockTest.lambda$main$1(DeadLockTest.java:32)
        - waiting to lock <0x00000000d648e630> (a java.lang.Object)
        - locked <0x00000000d648e640> (a java.lang.Object)
        at DeadLockTest$$Lambda$2/1831932724.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:748)
"Thread-0":
        at DeadLockTest.lambda$main$0(DeadLockTest.java:19)
        - waiting to lock <0x00000000d648e640> (a java.lang.Object)
        - locked <0x00000000d648e630> (a java.lang.Object)
        at DeadLockTest$$Lambda$1/990368553.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:748)

Found 1 deadlock.

jstack找出佔用cpu最高的堆棧信息

1,使用命令top -p <pid> ,顯示你的java進程的內存情況,pid是你的java進程號,比如4977

2,按H,獲取每個線程的內存情況

3,找到內存和cpu佔用最高的線程tid,比如4977

4,轉爲十六進制得到 0x1371 ,此爲線程id的十六進制表示

5,執行 jstack 4977|grep -A 10 1371,得到線程堆棧信息中1371這個線程所在行的後面10行

6,查看對應的堆棧信息找出可能存在問題的代碼

用jstack查找死鎖,見如下示例,也可以用jvisualvm查看死鎖 

JVisualVM使用

VisualVM,能夠監控線程,內存情況,查看方法的CPU時間和內存中的對 象,已被GC的
對象,反向查看分配的堆棧(如100個String對象分別由哪幾個對象分配出來的)。
VisualVM使用簡單,幾乎0配置,功能還是比較豐富的,幾乎囊括了其它JDK自帶命令的
所有功能。

  • 內存信息
  • 線程信息
  • Dump堆(本地進程)
  • Dump線程(本地進程)
  • 打開堆Dump。堆Dump可以用jmap來生成。
  • 打開線程Dump
  • 生成應用快照(包含內存信息、線程信息等等)
  • 性能分析。CPU分析(各個方法調用時間,檢查哪些方法耗時多),內存分析(各類
  • 對象佔用的內存,檢查哪些類佔用內存多)

 

 

遠程連接jvisualvm

JMX(Java Management Extensions,即Java管理擴展)是一個爲應用程序、設備、系統等植入管理功能的框架。JMX可以跨越一系列異構操作系統平臺、系統體系結構和網絡傳輸協議,靈活的開發無縫集成的系統、網絡和服務管理應用

啓動普通的jar程序JMX端口配置:

java -Dcom.sun.management.jmxremote.port=12345 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -jar foo.jar

java -Xms2048m -Xmx2048m -Xss256k -XX:MaxDirectMemorySize=256m -XX:+UseParallelOldGC -XX:+HeapDumpOnOutOfMemoryError -Djava.rmi.service.hostname=10.96.61.144 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dname=SmnService -cp ./ org.springframework.boot.loader.WarLauncher

啓動tomcat方式連接:

想要監控遠程的tomcat,就需要在遠程的tomcat進行對JMX配置,方法如下:

#在tomcat的bin目錄下,修改catalina.sh,添加如下的參數
JAVA_OPTS="‐Dcom.sun.management.jmxremote ‐
Dcom.sun.management.jmxremote.port=9999 ‐
Dcom.sun.management.jmxremote.authenticate=false ‐
Dcom.sun.management.jmxremote.ssl=false"
#這幾個參數的意思是:
#‐Dcom.sun.management.jmxremote :允許使用JMX遠程管理
#‐Dcom.sun.management.jmxremote.port=9999 :JMX遠程連接端口
#‐Dcom.sun.management.jmxremote.authenticate=false :不進行身份認證,任何用
戶都可以連接
#‐Dcom.sun.management.jmxremote.ssl=false :不使用ssl

保存退出,重啓tomcat。 

jhat使用

 使用MAT對dump文件分析

 這裏講一下需要在官網上下載內存分析工具

https://www.eclipse.org/downloads/download.php?file=/mat/1.9.1/rcp/MemoryAnalyzer-1.9.1.20190826-win32.win32.x86_64.zip

 

內存溢出實戰

內存溢出在實際的生產環境中經常會遇到,比如,不斷的將數據寫入到一個集合中,出現了死循環,讀取超大的文件等等,都可能會造成內存溢出。如果出現了內存溢出,首先我們需要定位到發生內存溢出的環節,並且進行分析,是正
常還是非正常情況,如果是正常的需求,就應該考慮加大內存的設置,如果是非正常需求,那麼就要對代碼進行修改,修復這個bug。首先,我們得先學會如何定位問題,然後再進行分析。如何定位問題呢,我們需要藉助於jmap與MAT工具進行定位分析。
接下來,我們模擬內存溢出的場景。

編寫代碼,向List集合中添加100萬個字符串,每個字符串由1000個UUID組成。如果程
序能夠正常執行,最後打印ok。

package cn.itcast.jvm;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class TestJvmOutOfMemory {
public static void main(String[] args) {
List<Object> list = new ArrayList<>();
for (int i = 0; i < 10000000; i++) {
String str = "";
for (int j = 0; j < 1000; j++) {
str += UUID.randomUUID().toString();
}
list.add(str);
}
System.out.println("ok");
}
}

爲了演示效果,我們將設置執行的參數,這裏使用的是Idea編輯器。

#參數如下:
‐Xms8m ‐Xmx8m ‐XX:+HeapDumpOnOutOfMemoryError

 

"C:\Program Files\Java\jdk1.8.0_45\bin\java.exe" -Xms8m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError "-javaagent:D:\software_install\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=65345:D:\software_install\IntelliJ IDEA 2018.2.4\bin" -3.10.5.Final.jar" com.itcast.memory.JVMOutOfMemory
java.lang.OutOfMemoryError: GC overhead limit exceeded
Dumping heap to java_pid41500.hprof ...
Heap dump file created [9292666 bytes in 0.024 secs]
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
	at java.util.Arrays.copyOf(Arrays.java:3332)
	at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:137)
	at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:121)
	at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:421)
	at java.lang.StringBuilder.append(StringBuilder.java:136)
	at java.util.UUID.toString(UUID.java:378)
	at com.itcast.memory.JVMOutOfMemory.main(JVMOutOfMemory.java:28)

Process finished with exit code 1

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章