
请点击【关注】获取更多互联网和技术干货,头条号IT徐胖子原创本文请勿转载,感谢支持
在开发过程中,我把项目中A团队开发的JAR包升级至最新版本,并发布上线。
运行了一段时间后,应用响应时间急剧上升,观察监控大盘,发现内存被吃掉了接近4个G。我首先立即回滚代码,业务恢复正常,然后排查定位问题。
如果在JVM脚本中配置了当发生内存泄漏时生成快照文件相关配置,则直接下载快照文件即可。配置脚本如下:
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/dump.hprof
如果没有在JVM脚本中配置,则登录问题机器执行jmap命令获取内存快照脚本。首先使用jps命令获取当前机器Java进程号,本例使用xxx表示,再执行如下脚本:
jmap -dump:format=b,file=/home/dump.hprof xxx
我把快照下载到本地进行分析。首先查看快照大小,竟然只有600M,这是有问题的。因为线上内存吃掉了4G,很明显600M这个内存快照有点太小了。
这时我想起了另外一个引发这个问题的原因:堆外内存泄漏。
我之所以快速猜想是堆外内存泄漏,是因为对操作系统内存结构比较熟悉。

堆、方法区、栈、堆外内存有任何一个超负荷,都会引起内存泄漏。由于我导出的内存快照是JVM内存快照,并且比较小,所以我快速定位是堆外内存泄漏。
我迅速将问题反馈给A团队,问他们是否在新版本中使用了堆外内存,得到了他们肯定的回答,随后他们迅速解决了这个问题。
出现这个问题,从我们团队考虑,版本不必追求最新。从A团队角度考虑,应该进行压力测试尽早发现问题。
请点击【关注】获取更多互联网和技术干货,头条号IT徐胖子原创本文请勿转载,感谢支持
| 留言与评论(共有 0 条评论) |