Java虚拟机性能管理神器 - VisualVM(6) 排查JAVA应用程序内存泄漏

1. 发现问题

线上应用部署完成后,运行12天左右就会出现假死,或者某天早上810点高峰期间突然不处理数据了。由于在测试环境的压力测试没有做完全,也没有遇到相关问题。情况出现后对客户的使用造成很大影响,领导要求赶紧排查出问题原因!

2. 排查原因

排查原因前,与运维沟通,了解线上服务器的运行状态,通过ganglila观察网络、CPU、内存、磁盘的运行历史状态,发现程序故障前,都有一波很高的负载,排查线上日志,负载来源在8~9点平台接入数据量成倍增加,通过与产品和市场人员分析,此时段是用户集中上班、接入平台的高峰时段,访问日志也显示,业务场景正常,无网络攻击和安全问题。属于产品业务正常的场景。

排除了网络安全因素后,就从程序的运行内部进行排查,首先想到的获取JVM的dmp文件。获取JVM的dmp文件有两中方式:

  1. JVM启动时增加两个参数,出现 OOME 时生成堆 dump:
   -XX:+HeapDumpOnOutOfMemoryError
         生成堆文件地址:
         -XX:HeapDumpPath=/home/test/jvmlogs/ 
  1. 发现程序异常前通过执行指令,直接生成当前JVM的dmp文件,15434是指JVM的进程号
   jmap -dump:format=b,file=serviceDump.dat    15434 

由于第一种方式是一种事后方式,需要等待当前JVM出现问题后才能生成dmp文件,实时性不高,第二种方式在执行时,JVM是暂停服务的,所以对线上的运行会产生影响。所以建议第一种方式。

3. 解决方案

获取到dmp文件后,就开始进行分析。将服务器上的dmp文件拷贝到本地,然后启动本地的VisualVM,点击菜单栏【文件】选项,装入dmp文件
在这里插入图片描述
打开dmp文件后,查看类标签,就能看到占用内存的一个排行。
在这里插入图片描述
然后通过检查中查找最大的对象,排查到具体线程和对象。
在这里插入图片描述
上列中的com.ctfo.trackservice.handler.TrackHandleThread#4就是重点排查对象。

通过代码的比对,在此线程中,有调用DAO接口,负责将数据存储到数据库中。而存储到数据库中时,由于存储速度较慢,导致此线程中的数据队列满了,数据积压,无法回收导致了队列锁定,结果就是程序假死,不处理数据。

通过进一步分析,发现数据库存储时有瓶颈,虽然当前是批量提交,速度也不快。平均8000/秒的存储速度。而数据库有一个DG(备份)节点,采用的是同步备份方式,即主库事务要等DG的事务也完成后才能返回成功,这样就会因为网络因素、DG性能因素等原因导致性能下降。通过与DBA、产品、沟通,将同步备份改为异步备份,实时同步改为异步(异步可能会导致主备有10分钟以内的数据延迟)。速度达到30000/秒。问题解决。
至此,通过VisualVM分析java程序内存泄漏到此结束。不过还有几个问题:1. 如果dmp文件较大,VisualVM分析时间可能很久;另外,VisualVM对堆的分析显示功能还不算全面。如果需要更全面的显示,就可以使用另外一个专业的dmp文件分析工具【Memory Analyzer (MAT)】,此工具可以作为eclipse的插件进行安装,也可以单独下载使用。如果有感兴趣的朋友,我个人建议还是单独下载使用。下载地址:http://www.eclipse.org/mat/

来源:CSDN
原文:https://blog.csdn.net/chwshuang/article/details/44202491

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值