背景: 新上线一个应用,大约跑了两三天,结果昨天测试小姐姐反馈我们接口响应比较慢,有时还会 503.于是去服务器上 top 查看了下,发现 Res 内存那项比较高,查看 cpu 负载和使用率都比较正常,于是怀疑内存泄漏,用 jmap 把内存 dump 下来,用 mat 进行分析发现 finalizer 对象占用异常高(如下图所示):
MAT 疑似内存泄漏分析试图:
点击 detail 可以看到里面引用(包装)的是 Object 对象:
然后与刚启动的内存 dump 对比:
通过查阅Java 的 Finalizer 引发的内存溢出,FinalizerReference 笔记,java.lang.ref.Finalizer 占用高内存等文章博客,大致知道是因为实现了 finalize()方法的对象在 GC 时不会直接被回收,还会放到一个 ReferenceQueue 队列中由一个低优先级的 finalizer 线程回收,由于该线程优先级低,很容易出现对象产生的速度远大于 finalizer 线程回收的速度,导致内存泄漏
然而.......别人都是自定义对象实现了 finalize(),我们这边看起来是 java.lang 的 Object(第三幅图,我们也可以看到项目里比起刚启动时增加三十多万 Object 对象)....我去项目里全局搜索查了下,没有找到生成如此多 Object 对象的代码,大部分使用 Object 的使用地方里面的实际对象也不是 Object,而是某个具体的子类对象,所以感觉非常难受.
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.