背景
收到某台服务器无法正常提供服务的报警,应用日志里没有新内容,再看catalina.out日志,发现报出OOM异常。
分析问题
因为OOM属于系统抛出的错误,因此没有写入到应用日志里,只在catalina.out日志里面有。
通过命令jmap -heap pid查看堆内存信息,发现空间确实满了。
考虑到有3G的内存,把内存dump出来查看本机受不了,故使用jmap -histo:live pid命令,查看对象的统计信息。如下图:
重点关注排名第九的类,因为它是我们架构组写的代码。
找到该类查看后,发现里面确实有静态的ConcurrentHashMap对象。初步可以断定是该类内存溢出导致。
粗略查看了下代码,发现静态的Map对象存在没有被释放的可能。而且代码里有些并发的逻辑写的也有些问题。
另外,将堆内存信息dump出来(jmap -dump:live,format=b,file=1.dump),然后让同事下载到本机用工具进行查看,发现这个类中Map对象数量惊人,达到了2-3G。
问题原因
将问题定位后,找架构组同事了解代码的功能:主线程拦截HttpClient的execute方法,将输出信息流CachedBufferedInputStream保存到M