返回

排查生产内存泄漏问题记

后端

事件背景
生产环境上,有一个应用部署的容器上,总是一两天自动重启一次,怀疑应该是内存溢出/泄漏导致。

排查过程分析
1、首先从pinpoint 监控上查看JVM的内存信息
如上图所示,Java应用设置了-Xms1024m-Xmx2048m的JVM堆参数,从Pinpoint上看,应用的JVM堆内存使用了1.8G,并不是很高。通过这段时间多次的JVM Heap Dump分析,并没有发现内存溢出的问题。

2、通过jmap -histo 命令查看内存泄漏信息
通过jmap命令查看内存泄漏信息,发现大量byte[]对象,并且这些对象并没有被及时回收。在经过分析发现,这些byte[]对象都是从Kafka中读取的日志数据,由于处理不及时,导致这些对象没有被及时回收,造成了内存泄漏。

3、解决问题
分析出问题原因后,我们优化了日志的处理逻辑,使得这些byte[]对象能够及时被回收,从而解决了内存泄漏问题。

优化后,应用的内存使用情况如下:

Heap
 PSYoungGen      total 921600K, used 404711K [0x0000000767980000, 0x0000000770b80000, 0x00000007c0000000)
  eden space 819200K, 49% used [0x0000000767980000, 0x000000076bb0d038, 0x000000076e780000)
  from space 102400K, 0% used [0x0000000770680000, 0x0000000770680000, 0x0000000770b80000)
  to   space 102400K, 0% used [0x0000000770b80000, 0x0000000770b80000, 0x0000000770e80000)
 ParOldGen       total 1024000K, used 985674K [0x00000007c0000000, 0x00000007c8000000, 0x00000007e0000000)
  object space 1024000K, 96% used [0x00000007c0000000, 0x00000007c7e2d448, 0x00000007c8000000)
 Metaspace       used 32297K, capacity 32928K, committed 33152K, reserved 1056960K
  class space    used 3163K, capacity 3424K, committed 3488K, reserved 1048576K

可以看出,优化后,应用的内存使用情况明显好转,内存泄漏问题也得到了解决。

通过这次事件,我们总结了以下经验教训:
1、在生产环境中,要定期监控应用的内存使用情况,及时发现并解决内存泄漏问题。
2、在处理大数据量时,要注意及时回收不用的对象,避免造成内存泄漏。
3、在排查内存泄漏问题时,可以结合Pinpoint监控、jmap命令等工具,快速定位问题所在。