美文网首页程序员
一次内存泄漏问题回顾

一次内存泄漏问题回顾

作者: 没有笔的Monkey | 来源:发表于2019-10-14 21:44 被阅读0次

问题现象:

运维通过内存监控发现,应用内存在每次跑批时会在短时间内(5分钟内)飙升10%左右(8G内存),且内存不会下降。

分析过程:

  1. 通过分析对应时间点的日志,分析可能是某个业务跑批导致,但查看代码并未能发现可能存在泄漏的地方;
  2. 通过代码扫描工具找到可能存在文件流未关闭的代码,修复后上线验证问题仍然存在,并无太大效果;
  3. 在内存飙升后,向运维申请生成JVM dump文件(起初运维不愿提供,来回折腾了一段时间);
  4. 使用MAT工具,结合代码分析dump文件:
    4.1 应用进程使用了5-6G内存,而dump文件只有1G左右、通过MAT查看堆内存只有200MB,怀疑是堆外内存泄漏;
    4.2 通过dump文件分析,发现MyBatis部分SQL缓存对象达到几十MB,查询SQL有优化空间,但不会造成很大内存泄漏;
  5. 往堆外内存泄漏方向排查
    5.1 通过MAT工具分析发现存在大量Finalizer对象、ByteBuffer对象;
    5.2 Finalizer对象持有大量OpenSsl对象(27万个),该OpenSsl为Apache加解密包里的类;
    5.3 定位到解密代码有用到ByteBuffer和CryptoCipher类;
    5.4 发现解密代码while循环,会循环创建CryptoCipher和ByteBuffer对象,每次跑批解密的文本数据量达到27万条,问题基本确认;
  6. 优化
    定位到问题后,接下来就好办了。优化代码,CryptoCipher对象和ByteBuffer对象复用。上线后观察多日,跑批后再无内存飙升现象,搞定收工!

总结

本次内存泄漏,从问题出现到定位到问题原因拖了较长时间。主要有如下几个原因:

  • 运维对dump命令不放心,申请dump文件僵持了一段时间;
  • 生产服务器无法查看java堆内存情况,不利于确认堆外还是堆内泄漏的排查方向;
  • MAT工具使用不够熟练;
  • 堆外内存泄漏排查经验不足,未能敏锐的识别到可能造成堆外内存泄漏的相关类;

参考链接:

一次堆外内存泄露的排查过程
Java内存泄漏的排查总结
java.lang.ref.Finalizer占用高内存

相关文章

  • 一次内存泄漏问题回顾

    问题现象: 运维通过内存监控发现,应用内存在每次跑批时会在短时间内(5分钟内)飙升10%左右(8G内存),且内存不...

  • Xcode调试工具

    一.静态内存分析工具 编译阶段查找内存泄漏等问题 1.常见内存泄漏问题 常见的内存泄漏除了循环引用,CoreFou...

  • 三个方法帮助解决Android内存泄漏问题

    三个方法帮助解决Android内存泄漏问题 最近自己遇到了好几个内存泄漏的问题,也帮同事解决了几个内存泄漏的问题记...

  • 内存泄漏和内存溢出的区别与解决方式

    内存泄漏(memory leak ) 是指程序在申请内存后,无法释放已申请的内存空间就造成了内存泄漏,一次内存泄漏...

  • 安卓内存泄漏

    Android 内存泄漏总结 内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题。内存泄漏...

  • Part1_Android内存泄漏总结

    Android 内存泄漏总结 内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题。内存泄漏...

  • Android 内存泄漏总结

    Android 内存泄漏总结 内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题。内存泄漏...

  • 【中级——高级迈不过去?】Android高级工程师进阶学习——A

    Android 内存泄漏总结 内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题。内存泄漏...

  • Android内存泄漏相关

    问题1 内存泄漏的基本定义是什么?内存泄漏有什么危害?问题2 开发中常见的内存泄漏的情况有哪些?什么原因造成的?怎...

  • iOS笔记-记录一次内存泄漏发现过程

    iOS笔记-记录一次内存泄漏发现过程 iOS笔记-记录一次内存泄漏发现过程

网友评论

    本文标题:一次内存泄漏问题回顾

    本文链接:https://www.haomeiwen.com/subject/ynedmctx.html