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

jinfo使用

可以查看java的系统参数

可以查看某个JVM的参数

可以调整某个JVM的参数

 查看jvm的参数

 
  1. λ jps

  2. 9920 jar

  3. 3524

  4. 1512 Launcher

  5. 10028 Jps

  6. λ jinfo -flags 9920

  7. Attaching to process ID 9920, please wait...

  8. Debugger attached successfully.

  9. Server compiler detected.

  10. JVM version is 25.171-b11

  11. 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

  12. Command line:

查看java系统参数

 
  1. λ jinfo -sysprops 9920

  2. Attaching to process ID 9920, please wait...

  3. Debugger attached successfully.

  4. Server compiler detected.

  5. JVM version is 25.171-b11

  6. java.runtime.name = Java(TM) SE Runtime Environment

  7. java.vm.version = 25.171-b11

  8. sun.boot.library.path = C:\Program Files\Java\jre1.8.0_171\bin

  9. java.protocol.handler.pkgs = org.springframework.boot.loader

  10. java.vendor.url = http://java.oracle.com/

  11. java.vm.vendor = Oracle Corporation

  12. path.separator = ;

  13. file.encoding.pkg = sun.io

  14. java.vm.name = Java HotSpot(TM) 64-Bit Server VM

  15. sun.os.patch.level = Service Pack 1

  16. sun.java.launcher = SUN_STANDARD

  17. user.script =

  18. user.country = CN

  19. 。。。。

Jstat

jstat命令可以查看堆内存各部分的使用量,以及加载类的数量。命令的格式如下:

jstat [-命令选项] [vmid] [间隔时间/毫秒] [查询次数]

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

 类加载统计:

 
  1. λ jstat.exe -class 9920

  2. Loaded Bytes Unloaded Bytes Time

  3. 10016 17802.1 0 0.0 16.63

  1. Loaded:加载class的数量
  2. Bytes:所占用空间大小
  3. Unloaded:未加载数量
  4. Bytes:未加载占用空间
  5. Time:时间

垃圾回收统计

 
  1. λ jstat.exe -gc 9920

  2. S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT

  3. 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

 

 
  1. λ jjstat.exe -gc 9920 1000 5

  2. #也可以指定打印的间隔和次数,每1秒中打印一次,共打印5次

  3. S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT

  4. 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

  5. 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

  6. 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

  7. 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

  8. 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:垃圾回收消耗总时间

堆内存统计: 

 
  1. λ jstat.exe -gccapacity 9920

  2. NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC

  3. 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次数

新生代内存统计

 
  1. λ jstat.exe -gcnew 9920

  2. S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT

  3. 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:老年代回收次数

 老年代垃圾回收统计

 
  1. λ jstat.exe -gcold 9920

  2. MC MU CCSC CCSU OC OU YGC FGC FGCT GCT

  3. 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:垃圾回收消耗总时间

老年代内存统计 

 
  1. λ jstat.exe -gcoldcapacity 9920

  2. OGCMN OGCMX OGC OC YGC FGC FGCT GCT

  3. 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:垃圾回收消耗总时间

元数据空间统计

 
  1. λ jstat.exe -gcmetacapacity 9920

  2. MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC FGCT GCT

  3. 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参数

 
  1. λ jstat.exe -gcutil 9920

  2. S0 S1 E O M CCS YGC YGCT FGC FGCT GCT

  3. 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可以获取到更加详细的内容,
如:内存使用情况的汇总、对内存溢出的定位与分析

堆信息:

 
  1. λ jmap.exe -heap 9920

  2. Attaching to process ID 9920, please wait...

  3. Debugger attached successfully.

  4. Server compiler detected.

  5. JVM version is 25.171-b11

  6.  
  7. using thread-local object allocation.

  8. Parallel GC with 4 thread(s)

  9.  
  10. Heap Configuration:

  11. MinHeapFreeRatio = 0

  12. MaxHeapFreeRatio = 100

  13. MaxHeapSize = 2105540608 (2008.0MB)

  14. NewSize = 44040192 (42.0MB)

  15. MaxNewSize = 701497344 (669.0MB)

  16. OldSize = 88080384 (84.0MB)

  17. NewRatio = 2

  18. SurvivorRatio = 8

  19. MetaspaceSize = 21807104 (20.796875MB)

  20. CompressedClassSpaceSize = 1073741824 (1024.0MB)

  21. MaxMetaspaceSize = 17592186044415 MB

  22. G1HeapRegionSize = 0 (0.0MB)

  23.  
  24. Heap Usage:

  25. PS Young Generation

  26. Eden Space:

  27. capacity = 672137216 (641.0MB)

  28. used = 176945008 (168.74790954589844MB)

  29. free = 495192208 (472.25209045410156MB)

  30. 26.325726918236885% used

  31. From Space:

  32. capacity = 11010048 (10.5MB)

  33. used = 9180504 (8.755210876464844MB)

  34. free = 1829544 (1.7447891235351562MB)

  35. 83.38296072823661% used

  36. To Space:

  37. capacity = 12058624 (11.5MB)

  38. used = 0 (0.0MB)

  39. free = 12058624 (11.5MB)

  40. 0.0% used

  41. PS Old Generation

  42. capacity = 93323264 (89.0MB)

  43. used = 32577656 (31.06847381591797MB)

  44. free = 60745608 (57.93152618408203MB)

  45. 34.90839754597525% used

  46.  
  47. 25513 interned Strings occupying 3131664 bytes.

 查看内存中对象数量及大小

 
  1. #查看所有对象,包括活跃以及非活跃的

  2. jmap ‐histo <pid> | more

  3. #查看活跃对象

  4. jmap ‐histo:live <pid> | more'

  5. λ jmap.exe -histo:live 9920 | more

  6.  
  7. num #instances #bytes class name

  8. ----------------------------------------------

  9. 1: 66633 8976600 [C

  10. 2: 64870 1556880 java.lang.String

  11. 3: 40185 1285920 java.util.concurrent.ConcurrentHashMap$Node

  12. 4: 10604 1178176 java.lang.Class

  13. 5: 8574 754512 java.lang.reflect.Method

  14. 6: 3987 734032 [B

  15. 7: 17124 684960 java.util.LinkedHashMap$Entry

  16. 8: 5074 684432 [I

  17. 9: 7759 550680 [Ljava.util.HashMap$Node;

  18. 10: 9423 527688 java.util.LinkedHashMap

  19. 11: 9325 518128 [Ljava.lang.Object;

  20. 12: 260 502688 [Ljava.util.concurrent.ConcurrentHashMap$Node;

  21. 13: 25660 410560 java.lang.Object

  22. 14: 12815 410080 java.util.HashMap$Node

  23. 15: 3754 150160 java.lang.ref.SoftReference

  24. 16: 1555 149280 org.springframework.beans.GenericTypeAwarePropertyDescriptor

  25. 17: 4567 146144 java.lang.ref.WeakReference

某测试环境发现部署的java进程(pid=1)经常full GC,长期内存占用很高,疑似内存泄漏,现在想要确定是哪些类的实例占用内存较多,那么应该用下列选项中的那个命令

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

 
  1. [service@usg-smn-191130100-8546f8ccd9-kfh6w usg]$ ./jdk1.8.0_151/bin/jmap -histo 1

  2. 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

  3.  
  4. num #instances #bytes class name

  5. ----------------------------------------------

  6. 1: 2296244 231628904 [C

  7. 2: 416554 53976048 [B

  8. 3: 6283 37337624 [J

  9. 4: 1360072 32641728 java.lang.String

  10. 5: 96883 18168224 [I

  11. 6: 253392 16217088 java.net.URL

  12. 7: 332371 15953808 java.util.HashMap

  13. 8: 260721 13617384 [Ljava.util.HashMap$Node;

  14. 9: 218684 12189896 [Ljava.lang.Object;

  15. 10: 257915 8253280 java.util.concurrent.locks.AbstractQueuedSynchronizer$Node

  16. 11: 244856 7835392 org.springframework.boot.loader.jar.StringSequence

  17. 12: 168575 6743000 java.util.LinkedHashMap$Entry

  18. 13: 244856 5876544

  19. #对象说明

  20. B byte

  21. C char

  22. D double

  23. F float

  24. I int

  25. J long

  26. Z boolean

  27. [ 数组,如[I表示int[]

  28. [L+类名 其他对象

  1. num:序号
  2. instances:实例数量
  3. bytes:占用空间大小
  4. class name:类名称

 

堆内存dump

有些时候我们需要将jvm当前内存中的情况dump到文件中,然后对它进行分析,jmap也
是支持dump到文件中的

 
  1. #用法:

  2. jmap ‐dump:format=b,file=dumpFileName <pid>

  3. #示例

  4. jmap ‐dump:format=b,file=/tmp/dump.dat 6219

  5. D:\

  6. λ jmap.exe -dump:format=b,file=eureka.hprof 9920

  7. Dumping heap to D:\eureka.hprof ...

  8. Heap dump file created

也可以设置内存溢出自动导出dump文件(内存很大的时候,可能会导不出来)

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

 

jstack的使用:

有些时候我们需要查看下jvm中的线程执行情况,比如,发现服务器的CPU的负载突然增
高了、出现了死锁、死循环等,我们该如何分析呢?
由于程序是正常运行的,没有任何的输出,从日志方面也看不出什么问题,所以就需要
看下jvm的内部线程的执行情况,然后再进行分析查找出原因。
这个时候,就需要借助于jstack命令了,jstack的作用是将正在运行的jvm的线程情况进
行快照,并且打印出来

#用法:jstack <pid>

 
  1. D:\IntelIJWorkSpace\jvm>jps

  2. 1264 Jps

  3. 3524

  4. 1512 Launcher

  5. 3516 DeadLockTest

  6.  
  7. D:\IntelIJWorkSpace\jvm>jstack 3516

  8. 2020-06-27 16:10:02

  9. Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.171-b11 mixed mode):

  10.  
  11. "DestroyJavaVM" #13 prio=5 os_prio=0 tid=0x00000000020e9000 nid=0x17ec waiting on condition [0x0000000000000000]

  12. java.lang.Thread.State: RUNNABLE

  13.  
  14. "Thread-1" #12 prio=5 os_prio=0 tid=0x00000000594c7800 nid=0xa54 waiting for monitor entry [0x000000005941f000]

  15. java.lang.Thread.State: BLOCKED (on object monitor)

  16. at DeadLockTest.lambda$main$1(DeadLockTest.java:32)

  17. - waiting to lock <0x00000000d648e630> (a java.lang.Object)

  18. - locked <0x00000000d648e640> (a java.lang.Object)

  19. at DeadLockTest$$Lambda$2/1831932724.run(Unknown Source)

  20. at java.lang.Thread.run(Thread.java:748)

  21.  
  22. "Thread-0" #11 prio=5 os_prio=0 tid=0x00000000594c2000 nid=0x1864 waiting for monitor entry [0x0000000059dbf000]

  23. java.lang.Thread.State: BLOCKED (on object monitor)

  24. at DeadLockTest.lambda$main$0(DeadLockTest.java:19)

  25. - waiting to lock <0x00000000d648e640> (a java.lang.Object)

  26. - locked <0x00000000d648e630> (a java.lang.Object)

  27. at DeadLockTest$$Lambda$1/990368553.run(Unknown Source)

  28. at java.lang.Thread.run(Thread.java:748)

  29.  
  30. "Service Thread" #10 daemon prio=9 os_prio=0 tid=0x0000000058559800 nid=0x668 runnable [0x0000000000000000]

  31. java.lang.Thread.State: RUNNABLE

  32.  
  33. "C1 CompilerThread2" #9 daemon prio=9 os_prio=2 tid=0x000000005854e800 nid=0x18bc waiting on condition [0x0000000000000000]

  34. java.lang.Thread.State: RUNNABLE

  35.  
  36. "C2 CompilerThread1" #8 daemon prio=9 os_prio=2 tid=0x000000005853d000 nid=0x1c0c waiting on condition [0x0000000000000000]

  37. java.lang.Thread.State: RUNNABLE

  38.  
  39. "C2 CompilerThread0" #7 daemon prio=9 os_prio=2 tid=0x000000005853c800 nid=0xf90 waiting on condition [0x0000000000000000]

  40. java.lang.Thread.State: RUNNABLE

  41.  
  42. "Monitor Ctrl-Break" #6 daemon prio=5 os_prio=0 tid=0x0000000058539800 nid=0x1860 runnable [0x00000000589fe000]

  43. java.lang.Thread.State: RUNNABLE

  44. at java.net.SocketInputStream.socketRead0(Native Method)

  45. at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)

  46. at java.net.SocketInputStream.read(SocketInputStream.java:171)

  47. at java.net.SocketInputStream.read(SocketInputStream.java:141)

  48. at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)

  49. at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)

  50. at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)

  51. - locked <0x00000000d652cb40> (a java.io.InputStreamReader)

  52. at java.io.InputStreamReader.read(InputStreamReader.java:184)

  53. at java.io.BufferedReader.fill(BufferedReader.java:161)

  54. at java.io.BufferedReader.readLine(BufferedReader.java:324)

  55. - locked <0x00000000d652cb40> (a java.io.InputStreamReader)

  56. at java.io.BufferedReader.readLine(BufferedReader.java:389)

  57. at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64)

  58.  
  59. "Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x00000000584e8800 nid=0x188c waiting on condition [0x0000000000000000]

  60. java.lang.Thread.State: RUNNABLE

  61.  
  62. "Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x00000000572c0000 nid=0x1d10 runnable [0x0000000000000000]

  63. java.lang.Thread.State: RUNNABLE

  64.  
  65. "Finalizer" #3 daemon prio=8 os_prio=1 tid=0x00000000572a5800 nid=0x19c0 in Object.wait() [0x00000000584df000]

  66. java.lang.Thread.State: WAITING (on object monitor)

  67. at java.lang.Object.wait(Native Method)

  68. - waiting on <0x00000000d6308ed0> (a java.lang.ref.ReferenceQueue$Lock)

  69. at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)

  70. - locked <0x00000000d6308ed0> (a java.lang.ref.ReferenceQueue$Lock)

  71. at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)

  72. at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:212)

  73.  
  74. "Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x0000000057264000 nid=0x19bc in Object.wait() [0x000000005819f000]

  75. java.lang.Thread.State: WAITING (on object monitor)

  76. at java.lang.Object.wait(Native Method)

  77. - waiting on <0x00000000d6306bf8> (a java.lang.ref.Reference$Lock)

  78. at java.lang.Object.wait(Object.java:502)

  79. at java.lang.ref.Reference.tryHandlePending(Reference.java:191)

  80. - locked <0x00000000d6306bf8> (a java.lang.ref.Reference$Lock)

  81. at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

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

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

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

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

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

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

  94.  
  95. JNI global references: 317

  96.  
  97.  
  98. Found one Java-level deadlock:

  99. =============================

  100. "Thread-1":

  101. waiting to lock monitor 0x00000000572b1148 (object 0x00000000d648e630, a java.lang.Object),

  102. which is held by "Thread-0"

  103. "Thread-0":

  104. waiting to lock monitor 0x00000000572ae758 (object 0x00000000d648e640, a java.lang.Object),

  105. which is held by "Thread-1"

  106.  
  107. Java stack information for the threads listed above:

  108. ===================================================

  109. "Thread-1":

  110. at DeadLockTest.lambda$main$1(DeadLockTest.java:32)

  111. - waiting to lock <0x00000000d648e630> (a java.lang.Object)

  112. - locked <0x00000000d648e640> (a java.lang.Object)

  113. at DeadLockTest$$Lambda$2/1831932724.run(Unknown Source)

  114. at java.lang.Thread.run(Thread.java:748)

  115. "Thread-0":

  116. at DeadLockTest.lambda$main$0(DeadLockTest.java:19)

  117. - waiting to lock <0x00000000d648e640> (a java.lang.Object)

  118. - locked <0x00000000d648e630> (a java.lang.Object)

  119. at DeadLockTest$$Lambda$1/990368553.run(Unknown Source)

  120. at java.lang.Thread.run(Thread.java:748)

  121.  
  122. 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。

 
  1. package cn.itcast.jvm;

  2. import java.util.ArrayList;

  3. import java.util.List;

  4. import java.util.UUID;

  5. public class TestJvmOutOfMemory {

  6. public static void main(String[] args) {

  7. List<Object> list = new ArrayList<>();

  8. for (int i = 0; i < 10000000; i++) {

  9. String str = "";

  10. for (int j = 0; j < 1000; j++) {

  11. str += UUID.randomUUID().toString();

  12. }

  13. list.add(str);

  14. }

  15. System.out.println("ok");

  16. }

  17. }

为了演示效果,我们将设置执行的参数,这里使用的是Idea编辑器。

 
  1. #参数如下:

  2. ‐Xms8m ‐Xmx8m ‐XX:+HeapDumpOnOutOfMemoryError

 

 
  1. "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

  2. java.lang.OutOfMemoryError: GC overhead limit exceeded

  3. Dumping heap to java_pid41500.hprof ...

  4. Heap dump file created [9292666 bytes in 0.024 secs]

  5. Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded

  6. at java.util.Arrays.copyOf(Arrays.java:3332)

  7. at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:137)

  8. at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:121)

  9. at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:421)

  10. at java.lang.StringBuilder.append(StringBuilder.java:136)

  11. at java.util.UUID.toString(UUID.java:378)

  12. at com.itcast.memory.JVMOutOfMemory.main(JVMOutOfMemory.java:28)

  13.  
  14. Process finished with exit code 1

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值