从一次netty 内存泄露问题来看netty对POST请求的解析

背景

最近生产环境一个基于 netty 的网关服务频繁 full gc

观察内存占用,并把时间维度拉的比较长,可以看到可用内存有明显的下降趋势

出现这种情况,按往常的经验,多半是内存泄露了

问题定位

找运维在生产环境 dump 了快照文件,一分析,果然不出所料,在一个 LinkedHashSet 里面, 放入 N 多的临时文件路径

可以看到,该 LinkedHashSet 是被类 DeleteOnExitHook 所引用。

DeleteOnExitHook

DeleteOnExitHook 是 jdk 提供的一个删除文件的钩子类,作用很简单,在 jvm 退出时,通过该类里面的钩子删除里面所记录的所有文件

我们简单的看下源码

class DeleteOnExitHook {
    private static LinkedHashSet<String> files = new LinkedHashSet<>();
    static {
        // 注册钩子, runHooks 方法在 jvm 退出的时候执行
        sun.misc.SharedSecrets.getJavaLangAccess()
            .registerShutdownHook(2 /* Shutdown hook invocation order */,
                true /* register even if shutdown in progress */,
                new Runnable() {
                    public void run() {
                       runHooks();
                    }
                }
        );
    }

    private DeleteOnExitHook() {}

    // 添加文件全路径到该类里面的set里
    static synchronized void add(String file) {
        if(files == null) {
            // DeleteOnExitHook is running. Too late to add a file
            throw new IllegalStateException("Shutdown in progress");
        }

        files.add(file);
    }

    static void runHooks() {
       // 省略代码。。。 该方法用做删除 files 里面记录的所有文件
    }
}

我们基本猜测出,在应用不断的运行过程中,不断有程序调用 DeleteOnExitHook.add方法,放入了大量临时文件路径,导致了内存泄露

其实关于 DeleteOnExitHook 类的设计,不少人认为这个类设计不合理,并且反馈给官方,但官方觉得是合理的,不打算改这个问题

有兴趣的可以看下 https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6664633

原因分析

既然已经定位到了出问题的地方,那么到底是什么情况下触发了这个 bug 了呢?

因为我们的网关是基于 netty 实现的,很快定位到了该问题是由 netty 引起的,但要说清楚这个问题并不容易

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值