1、查看当前堆的使用情况
[root@localhost ~]# jmap -heap pid
Attaching to process ID 27900, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 20.45-b01
using thread-local object allocation.
Mark Sweep Compact GC
Heap Configuration: #堆内存初始化配置
MinHeapFreeRatio = 40 #-XX:MinHeapFreeRatio设置JVM堆最小空闲比率
MaxHeapFreeRatio = 70 #-XX:MaxHeapFreeRatio设置JVM堆最大空闲比率
MaxHeapSize = 100663296 (96.0MB) #-XX:MaxHeapSize=设置JVM堆的最大大小
NewSize = 1048576 (1.0MB) #-XX:NewSize=设置JVM堆的‘新生代’的默认大小
MaxNewSize = 4294901760 (4095.9375MB) #-XX:MaxNewSize=设置JVM堆的‘新生代’的最大大小
OldSize = 4194304 (4.0MB) #-XX:OldSize=设置JVM堆的‘老生代’的大小
NewRatio = 2 #-XX:NewRatio=:‘新生代’和‘老生代’的大小比率
SurvivorRatio = 8 #-XX:SurvivorRatio=设置年轻代中Eden区与Survivor区的大小比值
PermSize = 12582912 (12.0MB) #-XX:PermSize=<value>:设置JVM堆的‘持久代’的初始大小
MaxPermSize = 67108864 (64.0MB) #-XX:MaxPermSize=<value>:设置JVM堆的‘持久代’的最大大小
Heap Usage:
New Generation (Eden + 1 Survivor Space): #新生代区内存分布,包含伊甸园区+1个Survivor区
capacity = 30212096 (28.8125MB)
used = 27103784 (25.848182678222656MB)
free = 3108312 (2.9643173217773438MB)
89.71169693092462% used
Eden Space: #Eden区内存分布
capacity = 26869760 (25.625MB)
used = 26869760 (25.625MB)
free = 0 (0.0MB)
100.0% used
From Space: #其中一个Survivor区的内存分布
capacity = 3342336 (3.1875MB)
used = 234024 (0.22318267822265625MB)
free = 3108312 (2.9643173217773438MB)
7.001809512867647% used
To Space: #另一个Survivor区的内存分布
capacity = 3342336 (3.1875MB)
used = 0 (0.0MB)
free = 3342336 (3.1875MB)
0.0% used
tenured generation: #当前的Old区内存分布
capacity = 67108864 (64.0MB)
used = 67108816 (63.99995422363281MB)
free = 48 (4.57763671875E-5MB)
99.99992847442627% used
Perm Generation: #当前的 “持久代” 内存分布
capacity = 14417920 (13.75MB)
used = 14339216 (13.674942016601562MB)
free = 78704 (0.0750579833984375MB)
99.45412375710227% used
2、查看当前大对象
jmap -histo:live pid| more
[root@prod-datacenter-dataservice system]# jmap -histo:live 4609 | more
num #instances #bytes class name
----------------------------------------------
1: 152068 16593328 [C
2: 19252 8136584 [I
3: 151456 3634944 java.lang.String
4: 11797 3362352 [B
5: 33753 3111216 [Ljava.lang.Object;
6: 35130 3091440 java.lang.reflect.Method
7: 86277 2760864 java.util.concurrent.ConcurrentHashMap$Node
8: 22327 2480840 java.lang.Class
9: 56796 1817472 java.util.HashMap$Node
10: 34467 1378680 java.util.LinkedHashMap$Entry
11: 14748 1375584 [Ljava.util.HashMap$Node;
12: 651 813064 [Ljava.util.concurrent.ConcurrentHashMap$Node;
13: 14316 801696 java.util.LinkedHashMap
14: 48968 783488 java.lang.Object
15: 24990 563064 [Ljava.lang.Class;
16: 18340 440160 java.util.ArrayList
17: 624 409344 io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueue
18: 4594 367520 java.lang.reflect.Constructor
19: 6986 335328 java.util.HashMap
20: 4387 315864 java.lang.reflect.Field
21: 6497 297032 [Ljava.lang.String;
22: 7228 289120 java.lang.ref.SoftReference
23: 11419 274056 org.springframework.core.MethodClassKey
24: 4458 213984 org.springframework.core.ResolvableType
25: 5203 166496 java.lang.ref.WeakReference
26: 3 165936 [Lcom.alibaba.druid.sql.parser.SymbolTable$Entry;
class name对应的值说明:
#instance 是对象的实例个数
#bytes 是总占用的字节数
class name 对应的就是 Class 文件里的 class 的标识
B 代表 byte
C 代表 char
D 代表 double
F 代表 float
I 代表 int
J 代表 long
Z 代表 boolean
前边有 [ 代表数组, [I 就相当于 int[]
对象用 [L+ 类名表示
3、采集内存快照
方式一
增加JVM启动参数,当出现OOM时自动保存内存快照
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/hybase-provide/logs/errmemory.dump
方式二
导出当前内存快照
jmap -dump:format=b,file=oom.dump pid
注意:这里保存下来的是.dump
4、使用专业工具进行分析
方式一:VisualVM
在idea中Terminal执行以下命令打开Java VisualVM
D:\code\new_git\hybase-provide>jvisualvm
导入需要分析的dump文件,导入的时候需要选择一下
下面是概览信息,包含了当前类个数和实例个数等,最重要的是给指出了发生OOM的线程和占用空间最大的对象(这两个信息很重要!)
点进去发生OOM的线程,大概是这个样子,这个时候肯定想定位到发生OOM的具体代码,别急,把这个线程下面的所有信息复制出来,根据自己的包名来查找具体代码
找到了的所有跟自己相关的代码
分析:出现OOM的可能性目前推测有以下几种:1、FazhibaoLog这个数据太多;2、保存的时候出现了问题。看了一下当天的数据,数据总量才5万+,不至于出现OOM,那么问题就有可能是第二个原因,用什么方法来佐证呢,别急,刚才概览页面右面不是还要最大对象排名,结合这个来分析。发现最大的对象占用居然是jdbc相关的,那么有没有可能是jdbc连接太多导致的原因呢?查看代码发现没有配置使用线程池,应该就是这个问题了。
方式二:JProfile
打开dump文件,注意这里的后缀要是.hprof,可以直接将.dump文件直接修改后缀
分析占用内存最大的对象
看左面的红色区域内的代码,是不是很熟悉,就是自己写的代码啊,把鼠标放上去还可以看到具体的代码位置
到此还是不能分析出出现OOM的问题,再去看下首页,也有一个最大对象tab,点击也能看到,占用最大的是jdbc相关的