记录一次OOM排查过程

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): #新生代区内存分布,包含伊甸园区+1Survivor区
   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相关的
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值