4-jvm性能调常用工具Jinfo Jstat Jmap Jstack jconsole 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最高的堆栈信息

0.查看java进程

root@ubuntu-130:/opt/jvm/tools# jps
21769 Demo1_16
17796 Jps

1,使用命令top查看那个线程占用cpu最多 21769

root@ubuntu-130:/opt/jvm/tools# top
top - 17:28:59 up 38 min,  2 users,  load average: 0.77, 0.27, 0.17
Tasks: 192 total,   1 running, 191 sleeping,   0 stopped,   0 zombie
%Cpu(s): 99.7 us,  0.3 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  2018048 total,   625092 free,   448524 used,   944432 buff/cache
KiB Swap:        0 total,        0 free,        0 used.  1312184 avail Mem

   PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
 21769   root      20   0 2410964  28732  16048 S 97.4  1.4   0:59.29 java
     8 root      20   0       0      0      0 S  0.3  0.0   0:01.01 rcu_sched

2,按H,获取每个线程的内存情况,找到内存和cpu占用最高的线程tid,比如453E

root@ubuntu-130:/opt/jvm/tools# ps H -eo pid,tid,%cpu | grep 21769
 21769  21769  0.0
 21769  21770  0.3
 21769  21771  0.0
 21769  21772  0.0
 21769  21773  0.0
 21769  21774  0.0
 21769  21775  0.0
 21769  21776  0.1
 21769  21777  0.0
 21769  21778  0.1
 21769  21779 96.6
 21769  21780  0.0
 21769  21781  0.0

4,转为十六进制得到 453E,此为线程id的十六进制表示

5,执行 jstack 21769|grep -A 10 453E,得到线程堆栈信息中1371这个线程所在行的后面11行,查看对应的堆栈信息找出可能存在问题的代码

jconsole:

图形化界面显示堆,线程,可以执行gc,查看应用程序信息

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

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值