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

时间:2015-03-03 01:38:39

标签: netty

我对Netty 5(或4)中的引用计数bytebuf有些怀疑。我发现当我没有在生命周期中释放bytebuf时没有任何反应,似乎bytebuf使用的内存可以正确地进行GC。

在此链接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 个答案:

答案 0 :(得分:3)

Netty中的资源泄漏检测机制依赖于ReferenceQueuePhantomReference。当一个对象(在我们的例子中是ReferenceQueue)变得无法访问时,垃圾收集器何时通知ByteBuf时,垃圾收集器不是很确定。如果VM过早终止或垃圾没有尽快收集,资源泄漏检测器无法判断是否有泄漏,因为垃圾收集器没有告诉我们任何事情。

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