当前位置: 首页 > 知识库问答 >
问题:

Netty 4/5实际上没有检测到Bytebuf的资源泄漏?

朱昊乾
2023-03-14

我对Netty5(或4)中的引用计数bytebuf有些怀疑。我发现,当bytebuf超出生命周期时,我不释放它时不会发生任何事情,似乎bytebuf使用的内存可以正确地GCed。

在这个链接http://netty.io/wiki/reference-counted-objects.html中,它说设置JVM选项'-dio.netty.leakdetectionlevel=advanced'或调用resourceleakdetector.setlevel()可以检测资源泄漏,但我不能用下面的代码复制它。

public class App {
    public static ByteBuf a(ByteBuf input) {
        input.writeByte(42);
        return input;
    }

    public static ByteBuf b(ByteBuf input) {
        try {
            ByteBuf output;
            output = input.alloc().directBuffer(input.readableBytes() + 1);
            output.writeBytes(input);
            output.writeByte(42);
            return output;
        } finally {
            // input.release();
        }
    }

    public static void c(ByteBuf input) {
        //System.out.println(input);
        // input.release();
    }

    static class Task implements Runnable {
        ByteBuf bbBuf;

        public Task(ByteBuf buf) {
            bbBuf = buf;
        }

        public void run() {
            c(b(a(bbBuf)));
        }
    }

    public static void main(String[] args) {
        ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.PARANOID);     
        AbstractByteBufAllocator allocator = new PooledByteBufAllocator();

        ByteBuf buf = allocator.buffer(10, 100);

        // buf.release();
        new Thread(new Task(buf)).start();
        System.out.println(buf.refCnt());
        assert buf.refCnt() == 0;
    }
}

那么问题出在哪里?

共有1个答案

戎元忠
2023-03-14

Netty中的资源泄漏检测机制依赖于ReferenceQueuePhantomReference。当一个对象(在本例中是bytebuf)变得无法访问时,垃圾回收器并不十分确定何时通知referencequeue。如果VM终止得太早或者垃圾收集得不够快,资源泄漏检测器就无法判断是否存在泄漏,因为垃圾收集器没有告诉我们任何事情。

实际上,这并不是一个问题,因为一个Netty应用程序在现实中通常会运行更长的时间,您最终会得到通知。只需运行一个应用程序大约30秒,让它做一些繁忙的工作。您肯定会看到泄漏错误消息。

 类似资料:
  • 我试图理解不对任何流调用close()会如何影响系统的性能和功能。为了做到这一点,我创建了下面的测试类。

  • 我们开发了一个spring-boot服务,它提供了一个rest api(spring-webflux)并通过RabbitMQ(spring-rabbit)发送数据。该服务部署在cloud foundry上,我们在版本2.1.4中使用spring-boot。我们添加了spring-boot-starter-data-redis来使用redis缓存一些数据,我们得到了以下错误: 我们这边相当迷茫,因为

  • Eclipse显示警告消息,表示"资源泄漏,准备好的语句未在以下位置关闭" 在我看来,finally块负责关闭preparedstatement和rs对象。你知道为什么eclipse还在抱怨资源泄漏吗?

  • 假设我用close()方法创建了一些资源类来清理资源,如果有人忘记调用close(),我想重写finalize()来释放资源(并打印警告)。这怎么做才算妥当呢? 是否只建议用于本机(JNI分配的)资源? 如果从终结器中使用对另一个已终结的对象的引用,会发生什么?如果存在循环依赖项,我不明白垃圾收集器如何阻止您访问终结器可能已执行的对象。 对于检测和/或处理资源泄漏,是否有更好的替代方法替代重写fi

  • https://docs.spring.io/spring-security/site/docs/5.0.5.release/reference/htmlsingle/#cors 我不确定这是由于我的CORS配置还是某些CSRF配置(就我而言,由于我的HttpSecurity配置,CSRF应该被禁用): 我已经尝试了各种其他建议的解决方案和旧的Spring Security版本的CORS配置,但到

  • Eclipse Java警告:资源泄漏:“Unassigned Closeable Value”从不关闭 漏在哪里?