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)

results matching ""

    No results matching ""