57

JVM 堆内存使用率持续上升的一种排查思路

 5 years ago
source link: http://www.10tiao.com/html/194/201806/2651481269/1.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

(点击上方公众号,可快速关注)


来源:木杉的博客 ,

imushan.com/2018/05/28/java/debug/JVM堆内存使用率持续上升的一种排查思路/


最近新版本发布后,在运行一段时间后程序突然无响应了,观察监控,发现JVM堆内存占用在某个时间点突然飙升,最终导致应用无响应:



重启Tomcat后,应用恢复正常,并且后续时间没有发生内存上涨问题。


分析这个JVM内存曲线,他是直线上升的,以前遇到过类似的场景,会导致这种直线(匀速)上升的,一般是一个死循环导致的,如果是普通请求资源泄露的话,上升曲线不会这么平稳,会和请求量有一定的关系。


死循环导致这个线程的资源无法释放,随着循环次数的增多,累积的对象越来越多,最终导致堆内存耗尽。


那要如何定位到具体的死循环位置呢?这个是个难题。之前遇到类似的问题是通过dump生产环境的JVM内存来分析,耗时耗力。结合之前的经验,这次我直接去nginx日志搜索响应码为504的请求,果不其然,在内存飙升时间点附近,有一个被响应504的请求。


504是什么响应码呢?这个响应码比较少遇到,指的是网关超时 (Gateway timeout)。当一个请求到Tomcat后,Tomcat如果陷入死循环,那么这个请求自然无法得到响应,nginx等待响应超时,响应给用户504。


504响应时间点和内存飙升时间点对的上,那么大概率就是这个接口导致的,详细分析这个接口的代码,发现了在特殊参数的情况下,会进入死循环,修改后问题解决。


总结:


  1. 观察JVM内存曲线,是否是匀速上升

  2. 搜索Nginx响应码为504的日志,查看日志时间是否和内存上升时间点匹配

  3. 分析Nginx响应码为504的请求,确认是否存在死循环逻辑


看完本文有收获?请转发分享给更多人

关注「ImportNew」,提升Java技能


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK