实际项目中查找频繁FullGC的原因,JVM内存监控,查找OOM的原因。定位内存泄漏的代码

    最近项目监控后台总是报:老年代内存使用率监控异常,频繁FullGC,30秒一次FullGC,CPU使用率超过90%,造成系统的性能迅速下降。频繁慢sql。总结一下排查JVM内存问题的过程和使用的工具。

1、刚开始发现频繁fullGC,所以查看了GC日志。

系统启动之后3天之后第一次fullGC,垃圾回收之后只释放了1600M左右的内存 都是新生代的内存,老年代几乎已经满了。

之后就开始频繁的Full GC ,几分钟就Full GC一次,最后就是30秒一次Full GC。系统的CPU飙升。当时并没有跑job,没有多大的数据量,老年代的对象只能是3天时间积累起来的,最后定位是内存泄漏。老年代对象无法回收。

2、第二步开始监控和诊断 JVM 堆内对象,需要使用jdk自带的综合性的图形化工具,如 JConsole、VisualVM,但是只能监控本地IDEA启动的程序,不能远程连接线上服务器。

通过监控可以查看程序运行是新生代对象的创建,GC频率,还是老年代对象的积累过程。

java visualVM监控页面

 

Java jconsole 显示页面

在visualVM中查看堆dump中的对象信息。如下图:

通过本地调试和排查,无法模拟线上复杂的环境,创建的垃圾对象也没有那么多。没有找到原因。

最后只有运维的同学帮我dump 了份线上生产环境的堆dump文件,用一下命令:

需要先用 ps -ef |grep "java"  查看 当前服务运行的Pid.

在执行下面的命令:

jmap -dump:format=b,file=20200513.dump 27379

最后在将生产的文件下载到本地:使用SSh客户端

scp -r ./20200513.dump gaocai@172.**.**.**:/d:/

生成.dump格式的文件,可以使用visualVM装入。开始分析。由于visualVM的软件功能有限,

我又下载了MemoryAnalyzer (MAT)和JProfiler来分析堆dump文件。

使用这两个工具分析需要将.dump文件的扩展名修改为.hprof格式。我先用MAT打开。

在overview页面可以看到大部分的内存 占用是problem内存对象890M。

我用到了Leak Suspects 和 Dominator 定位内存泄漏的问题代码。

1

 

 4

 

 从上图中可以看出,在VkRedis的MatricsFactory这个类中有一个ConcurrentHashMap对象占用了系统90%的内存。保存的是大量的SimpleMeterRegistry对象。

map的名字是  KEY_METER_REGISTRY_MAP  。在Java源带码中ctrl+N查询MatricsFactory类。发现:

 有一个定义成静态的map,名字也和查出来的一样。一天时间里边就保存了80万个Meter 对象。

 

以上定位到了内存泄漏的问题代码。是架构组的redis中间件有内存泄漏的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值