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] [间隔时间/毫秒] [查询次数]
类加载统计:
-
λ jstat.exe -class 9920
-
Loaded Bytes Unloaded Bytes Time
-
10016 17802.1 0 0.0 16.63
垃圾回收统计
-
λ 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
- S0C:第一个幸存区的大小 (Kb)
- S1C:第二个幸存区的大小 (Kb)
- S0U:第一个幸存区的使用大小 (Kb)
- S1U:第二个幸存区的使用大小 (Kb)
- EC:伊甸园区的大小 (Kb)
- EU:伊甸园区的使用大小 (Kb)
- OC:老年代大小 (Kb)
- OU:老年代使用大小 (Kb)
- MC:方法区大小(元空间) (Kb)
- MU:方法区使用大小 (Kb)
- CCSC:压缩类空间大小 (Kb)
- CCSU:压缩类空间使用大小
- YGC:年轻代垃圾回收次数
- YGCT:年轻代垃圾回收消耗时间
- FGC:老年代垃圾回收次数
- FGCT:老年代垃圾回收消耗时间
- 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
- NGCMN:新生代最小容量
- NGCMX:新生代最大容量
- NGC:当前新生代容量
- S0C:第一个幸存区大小
- S1C:第二个幸存区的大小
- EC:伊甸园区的大小
- OGCMN:老年代最小容量
- OGCMX:老年代最大容量
- OGC:当前老年代大小
- OC:当前老年代大小
- MCMN:最小元数据容量
- MCMX:最大元数据容量
- MC:当前元数据空间大小
- CCSMN:最小压缩类空间大小
- CCSMX:最大压缩类空间大小
- CCSC:当前压缩类空间大小
- YGC:年轻代gc次数
- 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
- NGCMN:新生代最小容量
- NGCMX:新生代最大容量
- NGC:当前新生代容量
- S0CMX:最大幸存1区大小
- S0C:当前幸存1区大小
- S1CMX:最大幸存2区大小
- S1C:当前幸存2区大小
- ECMX:最大伊甸园区大小
- EC:当前伊甸园区大小
- YGC:年轻代垃圾回收次数
- 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
- MC:方法区大小
- MU:方法区使用大小
- CCSC:压缩类空间大小
- CCSU:压缩类空间使用大小
- OC:老年代大小
- OU:老年代使用大小
- YGC:年轻代垃圾回收次数
- FGC:老年代垃圾回收次数
- FGCT:老年代垃圾回收消耗时间
- 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
- OGCMN:老年代最小容量
- OGCMX:老年代最大容量
- OGC:当前老年代大小
- OC:老年代大小
- YGC:年轻代垃圾回收次数
- FGC:老年代垃圾回收次数
- FGCT:老年代垃圾回收消耗时间
- 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
- MCMN:最小元数据容量
- MCMX:最大元数据容量
- MC:当前元数据空间大小
- CCSMN:最小压缩类空间大小
- CCSMX:最大压缩类空间大小
- CCSC:当前压缩类空间大小
- YGC:年轻代垃圾回收次数
- FGC:老年代垃圾回收次数
- FGCT:老年代垃圾回收消耗时间
- 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
- S0:幸存1区当前使用比例
- S1:幸存2区当前使用比例
- E:伊甸园区使用比例
- O:老年代使用比例
- M:元数据区使用比例
- CCS:压缩使用比例
- YGC:年轻代垃圾回收次数
- FGC:老年代垃圾回收次数
- FGCT:老年代垃圾回收消耗时间
- 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+类名 其他对象
堆内存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文件(内存很大的时候,可能会导不出来)
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
4,转为十六进制得到 0x1371 ,此为线程id的十六进制表示
5,执行 jstack 4977|grep -A 10 1371,得到线程堆栈信息中1371这个线程所在行的后面10行
用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可以跨越一系列异构操作系统平台、系统体系结构和网络传输协议,灵活的开发无缝集成的系统、网络和服务管理应用
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文件分析
这里讲一下需要在官网上下载内存分析工具
内存溢出实战
内存溢出在实际的生产环境中经常会遇到,比如,不断的将数据写入到一个集合中,出现了死循环,读取超大的文件等等,都可能会造成内存溢出。如果出现了内存溢出,首先我们需要定位到发生内存溢出的环节,并且进行分析,是正
常还是非正常情况,如果是正常的需求,就应该考虑加大内存的设置,如果是非正常需求,那么就要对代码进行修改,修复这个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