linux 内存溢出排查_linux MAT排查解决java项目内存溢出 OutOfMemoryError: Java heap space...

使用java springboot开发了一个项目来调用cdp4j来操作chrome浏览器,但是调用浏览器访问页面越多,占用内存就越大,直到内存溢出

这就是典型的调用第三方框架,导致的内存溢出,而并不清楚第三方框架中哪个代码导致了 内存溢出

1.异常信息:

java.lang.OutOfMemoryError: Java heap space

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

at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124)

at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:596)

at java.lang.StringBuilder.append(StringBuilder.java:190)

at com.google.gson.stream.JsonReader.nextQuotedValue(JsonReader.java:1029)

at com.google.gson.stream.JsonReader.nextString(JsonReader.java:816)

at com.google.gson.internal.bind.TypeAdapters$29.read(TypeAdapters.java:702)

at com.google.gson.internal.bind.TypeAdapters$29.read(TypeAdapters.java:723)

at com.google.gson.internal.bind.TypeAdapters$29.read(TypeAdapters.java:723)

at com.google.gson.internal.bind.TypeAdapters$29.read(TypeAdapters.java:698)

at com.google.gson.internal.bind.TypeAdapters$35$1.read(TypeAdapters.java:894)

at com.google.gson.Gson.fromJson(Gson.java:932)

at com.google.gson.Gson.fromJson(Gson.java:897)

at com.google.gson.Gson.fromJson(Gson.java:846)

at com.google.gson.Gson.fromJson(Gson.java:817)

at io.webfolder.cdp.session.MessageHandler.lambda$process$1(MessageHandler.java:69)

at io.webfolder.cdp.session.MessageHandler$$Lambda$671/1544658000.run(Unknown Source)

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)

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

2.原因分析:

2.1内存持续变大的原因只有一个,那就是对象一直被持有,垃圾回收不了,查看一下哪些变量和对象占用内存最多

jmap命令是一个可以输出所有内存中对象的工具

$ jmap -histo:live 32556|head -n 20

num #instances #bytes class name

----------------------------------------------

1: 79360 5422368 [C

2: 79194 1900656 java.lang.String

3: 32489 1559472 com.google.gson.internal.LinkedTreeMap$Node

4: 6271 1167296 [I

5: 10577 1164536 java.lang.Class

6: 35775 1144800 java.util.concurrent.ConcurrentHashMap$Node

7: 9031 1143848 [Ljava.lang.Object;

8: 4302 919928 [B

9: 36983 591728 java.lang.Object

10: 4500 504000 java.net.SocksSocketImpl

11: 10177 488496 com.google.gson.internal.LinkedTreeMap

12: 5369 472472 java.lang.reflect.Method

13: 10314 412560 java.lang.ref.Finalizer

14: 8625 345000 java.util.LinkedHashMap$Entry

15: 173 339328 [Ljava.util.concurrent.ConcurrentHashMap$Node;

16: 3099 289152 [Ljava.util.HashMap$Node;

17: 16221 259536 com.google.gson.JsonPrimitive

2.2将内存信息导出到文件中

$ jmap -dump:format=b,file=filename.bin 32556

Dumping heap to /home/server/filename.bin ...

Heap dump file created

2.3使用Memory Analyzer (MAT)工具分析内存信息

下载后先修改MemoryAnalyzer.ini 修改里面的参数如-Xmx5120m(最好要大于你的堆转储文件)

然后打开 MemoryAnalyzer.exe

然后打开导出的内存文件:文件-OPEN-Heap Dump

“Leak Suspects"一般会显示MAT它自己认为有问题的内容

同时在你导入内存文件的同级文件会产生一个html版的报告,filename_Leak_Suspects.zip。这就相当于一份离线的报告,和界面上的一样只是方便保存,毕竟分析也是需要时间的,但并没有界面上功能齐全。

点击推荐问题的Detail,进入到详情页

直接查看 Accumulated Objects in Dominator Tree 来查看内存是在哪个对象中被占着,并且点击一下,然后选择List object-with outgoing references,因为我的很明显有个static 数组,我是用来作为连接池的,这个连接池里面持有的对象,不断变大,我需要用with outgoing references来查看具体持有的哪个对象在不断增大

接着你只需要点击占用内存大的对象一步一步查找,主要是看 shallow heap(浅堆) 和 retained heap(深堆)

然后发现一个hashmap累计了大量的对象占用了内存

现在你只需要清空这个map或者将持有这个map的对象设置为null,内存就会自动回收!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值