我对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;
}
}
那么问题是什么?
答案 0 :(得分:3)
Netty中的资源泄漏检测机制依赖于ReferenceQueue
和PhantomReference
。当一个对象(在我们的例子中是ReferenceQueue
)变得无法访问时,垃圾收集器何时通知ByteBuf
时,垃圾收集器不是很确定。如果VM过早终止或垃圾没有尽快收集,资源泄漏检测器无法判断是否有泄漏,因为垃圾收集器没有告诉我们任何事情。
实际上,这不是一个问题,因为Netty应用程序通常会在更长的时间内运行,并且最终会得到通知。只需运行一个应用程序约30秒,让它做一些繁忙的工作。你肯定应该看到泄漏错误信息。