出现场景:
首先是收到云上的测试项目突然出现了登陆不了的问题,所有的页面都是空白,加载不出来.
然后linux中的进行了top操作查看cpu使用情况:
此时发现cpu已经的满载的371%了.
排查过程:
1.首先看了一下云上tomcat的错误日志发现了这个错误:OutOfMemoryError: GC overhead limit exceeded
总结了一下是jvm的内存溢出,当时我的代码中有着许多的流操作,我第一时间怀疑的是流导致的内存溢出
2.使用 printf "%x " 9673 打印对应进程的16进制代码(虽然我后面的排查也没有用上这个代码)
3.使用java虚拟机自带的堆栈跟踪工具 jstack 9673 > log.txt 打印jvm中的日志信息(建议sz到windows桌面看更直观)
就是这个文件
4.我看很多人都是使用进程16制的值搜索,更精确的搜索出对应的出错位置,可是我发现这对我好像没有什么帮助,我没有找到具体的出错位置.
e.g:
上面提到了我知道差不多是在哪个位置出现的问题,所以我直接使用了那个impl的名称去搜索
然后找到了关键所在
5.之后重新阅读了代码发现因为逻辑太过复杂和繁琐,有一处应该使用的map.replace(),测试时写成了map.put()并且后来也没有更正回来导致死循环.
重新将代码更正然后重新发布,不再出现问题.
留在最后:
也可以使用工具visualvm(性能分期)和工具tda.bat(网上看见有人推荐,可以打印出比jvm更详细的日志方便阅读),帮助排除错误,因为这次我碰到的错误比较低级也没有那么复杂,所以也就不再过多深入了.
自己记录一下,顺便给碰到cpu满载无从下手的朋友们参考一下.