记录一次Java项目堆外内存泄漏排查经历

请点击【关注】获取更多互联网和技术干货,头条号IT徐胖子原创本文请勿转载,感谢支持


1 问题背景

在开发过程中,我把项目中A团队开发的JAR包升级至最新版本,并发布上线。

运行了一段时间后,应用响应时间急剧上升,观察监控大盘,发现内存被吃掉了接近4个G。我首先立即回滚代码,业务恢复正常,然后排查定位问题。


2 获取内存快照文件

如果在JVM脚本中配置了当发生内存泄漏时生成快照文件相关配置,则直接下载快照文件即可。配置脚本如下:

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/dump.hprof

如果没有在JVM脚本中配置,则登录问题机器执行jmap命令获取内存快照脚本。首先使用jps命令获取当前机器Java进程号,本例使用xxx表示,再执行如下脚本:

jmap -dump:format=b,file=/home/dump.hprof xxx


3 关于内存快照的疑问

我把快照下载到本地进行分析。首先查看快照大小,竟然只有600M,这是有问题的。因为线上内存吃掉了4G,很明显600M这个内存快照有点太小了。

这时我想起了另外一个引发这个问题的原因:堆外内存泄漏。


4 操作系统内存结构

我之所以快速猜想是堆外内存泄漏,是因为对操作系统内存结构比较熟悉。

堆、方法区、栈、堆外内存有任何一个超负荷,都会引起内存泄漏。由于我导出的内存快照是JVM内存快照,并且比较小,所以我快速定位是堆外内存泄漏。


5 问题总结

我迅速将问题反馈给A团队,问他们是否在新版本中使用了堆外内存,得到了他们肯定的回答,随后他们迅速解决了这个问题。

出现这个问题,从我们团队考虑,版本不必追求最新。从A团队角度考虑,应该进行压力测试尽早发现问题。

请点击【关注】获取更多互联网和技术干货,头条号IT徐胖子原创本文请勿转载,感谢支持

发表评论
留言与评论(共有 0 条评论)
   
验证码:

相关文章

推荐文章

'); })();