Java 内存占用分析

1. 查看当前系统 jvm 内存分配 : jmap -heap [PID]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
[root@server]# jmap -heap 18932
Attaching to process ID 18932, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.201-b09

using thread-local object allocation.
Parallel GC with 18 thread(s)

Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 8422162432 (8032.0MB)
NewSize = 175112192 (167.0MB)
MaxNewSize = 2807037952 (2677.0MB)
OldSize = 351272960 (335.0MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)

Heap Usage:
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.tools.jmap.JMap.runTool(JMap.java:201)
at sun.tools.jmap.JMap.main(JMap.java:130)
Caused by: java.lang.RuntimeException: unknown CollectedHeap type : class sun.jvm.hotspot.gc_interface.CollectedHeap
at sun.jvm.hotspot.tools.HeapSummary.run(HeapSummary.java:157)
at sun.jvm.hotspot.tools.Tool.startInternal(Tool.java:260)
at sun.jvm.hotspot.tools.Tool.start(Tool.java:223)
at sun.jvm.hotspot.tools.Tool.execute(Tool.java:118)
at sun.jvm.hotspot.tools.HeapSummary.main(HeapSummary.java:50)
... 6 more
  • 出现异常的原因是没有安装jdk debuginfo, 需要安装 java-1.8.0-openjdk-debuginfo.xxxx,注意版本号

2. 查看当前 jvm 内存使用量

1
2
3
[root@test]# jstat -gc 23688
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
8704.0 8704.0 7680.0 0.0 2723328.0 242485.2 926208.0 880316.7 104704.0 99592.0 11264.0 10300.2 7168 135.426 7 1.771 137.198
  • S0C:第一个幸存区的大小
  • S1C:第二个幸存区的大小
  • S0U:第一个幸存区的使用大小
  • S1U:第二个幸存区的使用大小
  • EC:伊甸园区的大小
  • EU:伊甸园区的使用大小
  • OC:老年代大小
  • OU:老年代使用大小
  • MC:方法区大小
  • MU:方法区使用大小
  • CCSC: 压缩类空间大小
  • CCSU: 压缩类空间使用大小
  • YGC:年轻代垃圾回收次数
  • YGCT:年轻代垃圾回收消耗时间
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间
  • GCT:垃圾回收消耗总时间

3. 查看 jvm 最近一次 gc 的统计和原因 : jstat -gccause [PID]

1
2
3
   [root@test]# jstat -gccause 18932
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT LGCC GCC
90.81 0.00 37.71 94.93 95.12 91.44 7166 135.412 7 1.771 137.183 Allocation Failure No GC
  • S0 — Heap上的 Survivor space 0 区已使用空间的百分比
  • S1 — Heap上的 Survivor space 1 区已使用空间的百分比
  • E — Heap上的 Eden space 区已使用空间的百分比
  • O — Heap上的 Old space 区已使用空间的百分比
  • M — 元数据 区已使用空间的百分比
  • CCS — 压缩使用比例
  • YGC — 从应用程序启动到采样时发生 Young GC 的次数
  • YGCT– 从应用程序启动到采样时 Young GC 所用的时间(单位秒)
  • FGC — 从应用程序启动到采样时发生 Full GC 的次数
  • FGCT– 从应用程序启动到采样时 Full GC 所用的时间(单位秒)
  • GCT — 从应用程序启动到采样时用于垃圾回收的总时间(单位秒)
  • LGC — 上次GC发生的原因
  • GCC - 当前GC的原因

4. 使用 jmap dump整个 堆内存到文件

1
jmap -dump:format=b,file=filename.bin [pid]

5. 使用 eclipse MAT 工具分析内存

MAT 官网下载地址

5.1. 安装,打开 MAT

5.2. MAT 设置

  • MAT默认是只分析reachable对象实例,所以在”Preferences=>Memory Analyzer”中勾选”Keep Unreachable Objects”,删除索引文件Dump同路径下的所有”.index”,即可看到所有的对象,再根据上述步骤4进行分析
  • 修改堆内存大小,修改 mat.app/Contents/Eclipse/MemoryAnalyzer.ini 文件中的 -Xmx 的dance,比如修改为: -Xmx6192M,表示修改堆内存为 6G.

5.3. 分析到底是哪个对象占用内存过大

Just for my love !!