V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
LinkedIn
ZiLong
V2EX  ›  问与答

Java 疑似 finalizer 内存泄漏问题,不知如何下手了?

  •  
  •   ZiLong · 2020-07-31 11:30:39 +08:00 · 1437 次点击
    这是一个创建于 787 天前的主题,其中的信息可能已经有所发展或是发生改变。

    背景: 新上线一个应用,大约跑了两三天,结果昨天测试小姐姐反馈我们接口响应比较慢,有时还会 503.于是去服务器上 top 查看了下,发现 Res 内存那项比较高,查看 cpu 负载和使用率都比较正常,于是怀疑内存泄漏,用 jmap 把内存 dump 下来,用 mat 进行分析发现 finalizer 对象占用异常高(如下图所示):

    MAT 疑似内存泄漏分析试图: blcQH.png

    点击 detail 可以看到里面引用(包装)的是 Object 对象: blUYL.png

    然后与刚启动的内存 dump 对比: blb3f.png

    通过查阅Java 的 Finalizer 引发的内存溢出,FinalizerReference 笔记,java.lang.ref.Finalizer 占用高内存等文章博客,大致知道是因为实现了 finalize()方法的对象在 GC 时不会直接被回收,还会放到一个 ReferenceQueue 队列中由一个低优先级的 finalizer 线程回收,由于该线程优先级低,很容易出现对象产生的速度远大于 finalizer 线程回收的速度,导致内存泄漏

    然而.......别人都是自定义对象实现了 finalize(),我们这边看起来是 java.lang 的 Object(第三幅图,我们也可以看到项目里比起刚启动时增加三十多万 Object 对象)....我去项目里全局搜索查了下,没有找到生成如此多 Object 对象的代码,大部分使用 Object 的使用地方里面的实际对象也不是 Object,而是某个具体的子类对象,所以感觉非常难受.

    是否是我遗漏了什么细节,导致结论(=>Object 的锅)有问题?

    还是结论正确,需要再仔细查找项目?

    还请走过路过的各位 Javaer 指点下迷津,下一步该干什么?

    2 条回复    2020-08-02 21:58:31 +08:00
    ChanKc
        1
    ChanKc  
       2020-07-31 12:45:45 +08:00
    static void register(Object finalizee) {

    new Finalizer(finalizee);

    }

    所以都是 Object 吧,不看代码应该很难确定是什么 Object
    zizon
        2
    zizon  
       2020-08-02 21:58:31 +08:00
    socket 对象有点多?看下连接数正常不?
    不正常的话应该就是连接管理有问题?
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1135 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 39ms · UTC 21:40 · PVG 05:40 · LAX 14:40 · JFK 17:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.