netty中为了方便监控ByteBuf的泄露, 实现了两个LeakAwareByteBuf:
- AdvancedLeakAwareByteBuf
- SimpleLeakAwareByteBuf
调用方式
AdvancedLeakAwareByteBuf和SimpleLeakAwareByteBuf和resource leak detect相关,在方法 AbstractByteBufAllocator.toLeakAwareBuffer()中被调用,分别对应resource leak detect的不同级别:
protected static ByteBuf toLeakAwareBuffer(ByteBuf buf) {
    ResourceLeak leak;
    switch (ResourceLeakDetector.getLevel()) {
        case SIMPLE:
            leak = AbstractByteBuf.leakDetector.open(buf);
            if (leak != null) {
                buf = new SimpleLeakAwareByteBuf(buf, leak);
            }
            break;
        case ADVANCED:
        case PARANOID:
            leak = AbstractByteBuf.leakDetector.open(buf);
            if (leak != null) {
                buf = new AdvancedLeakAwareByteBuf(buf, leak);
            }
            break;
        default:
            break;
    }
    return buf;
}
toLeakAwareBuffer()方法在以下几个地方被调用,都是用来将普通ByteBuf包装为LeakAwareBuffer.
- PooledByteBufAllocator.newDirectBuffer()
- PooledByteBufAllocator.newHeapBuffer()
- UnpooledByteBufAllocator.newDirectBuffer()
代码类似如下:
protected ByteBuf newDirectBuffer(int initialCapacity, int maxCapacity) {
    // 创建目标ByteBuf
    ByteBuf buf = ......;
    // 包装为LeakAwareBuffer
    return toLeakAwareBuffer(buf);
}
总结: 在使用ByteBufAllocator分配ByteBuf时,netty会根据当前的resource detect level的设置使用对应的AdvancedLeakAwareByteBuf或SimpleLeakAwareByteBuf包装真实的ByteBuf
代码实现
AdvancedLeakAwareByteBuf
构造函数中传入需要包装的ByteBuf和ResourceLeak对象:
final class AdvancedLeakAwareByteBuf extends WrappedByteBuf {
    private final ResourceLeak leak;
    AdvancedLeakAwareByteBuf(ByteBuf buf, ResourceLeak leak) {
        super(buf);
        this.leak = leak;
    }
    ......
}
然后几乎所有的方法,都在delegate之前多加一句对leak.record()的调用:
public double getDouble(int index) {
    leak.record();
    return super.getDouble(index);
}
然后所有的slice()/duplicate()/readSlice()/order()方法都在返回新的ByteBuf前再次包装成AdvancedLeakAwareByteBuf:
public ByteBuf slice() {
    leak.record();
    return new AdvancedLeakAwareByteBuf(super.slice(), leak);
}
SimpleLeakAwareByteBuf
实现方式基本和AdvancedLeakAwareByteBuf相似,但是只有一个方法添加了对leak.record()的调用:
- order(ByteOrder endianness)