Netty之Buffer(四)ByteBufAllocator

本文深入解析Netty中的UnpooledByteBufAllocator类,探讨其作为非内存池ByteBuf分配器的工作原理,包括如何监控Heap和Direct内存使用情况,以及不同JDK版本下内存计数器的实现。
摘要由CSDN通过智能技术生成

这会看ByteBufAllocator最后一个子类:UnpooledByteBufAllocator,不基于内存池的ByteBuf分配器。
ByteBufAllocatorMetricProvider中,ByteBufAllocatorMetric提供者接口,用于监控ByteBuf的Heap和Direct 占用内存的情况:

public interface ByteBufAllocatorMetricProvider {

    /**
     * Returns a {@link ByteBufAllocatorMetric} for a {@link ByteBufAllocator}.
     */
    ByteBufAllocatorMetric metric();

}

ByteBufAllocatorMetric:

public interface ByteBufAllocatorMetric {

    /**
     * Returns the number of bytes of heap memory used by a {@link ByteBufAllocator} or {@code -1} if unknown.
     *
     * 已使用 Heap 占用内存大小
     */
    long usedHeapMemory();

    /**
     * Returns the number of bytes of direct memory used by a {@link ByteBufAllocator} or {@code -1} if unknown.
     *
     * 已使用 Direct 占用内存大小
     */
    long usedDirectMemory();

}

UnpooledByteBufAllocatorMetric ,在 UnpooledByteBufAllocator 的内部静态类,实现 ByteBufAllocatorMetric 接口,UnpooledByteBufAllocator Metric 实现类。

/**
 * Direct ByteBuf 占用内存大小
 */
final LongCounter directCounter = PlatformDependent.newLongCounter();
/**
 * Heap ByteBuf 占用内存大小
 */
final LongCounter heapCounter = PlatformDependent.newLongCounter();

@Override
public long usedHeapMemory() {
    return heapCounter.value();
}

@Override
public long usedDirectMemory() {
    return directCounter.value();
}

两个计数器:
PlatformDependent#newLongCounter() 方法,获得 LongCounter 对象:

/**
 * Creates a new fastest {@link LongCounter} implementation for the current platform.
 */
public static LongCounter newLongCounter() {
    if (javaVersion() >= 8) {
        return new LongAdderCounter();
    } else {
        return new AtomicLongCounter();
    }
}

根据JDK版本,JDK >=8 使用 java.util.concurrent.atomic.LongAdder ,JDK <7 使用 java.util.concurrent.atomic.AtomicLong 。

UnpooledByteBufAllocator实现 ByteBufAllocatorMetricProvider 接口,继承 AbstractByteBufAllocator 抽象类,普通的 ByteBuf 的分配器,不基于内存池。
构造:

/**
 * Metric
 */
private final UnpooledByteBufAllocatorMetric metric = new UnpooledByteBufAllocatorMetric();
/**
 * 是否禁用内存泄露检测功能,disableLeakDetector
 */
private final boolean disableLeakDetector;
/**
 * 不使用 `io.netty.util.internal.Cleaner` 释放 Direct ByteBuf
 *
 * @see UnpooledUnsafeNoCleanerDirectByteBuf
 * @see InstrumentedUnpooledUnsafeNoCleanerDirectByteBuf
 */
private final boolean noCleaner;

public UnpooledByteBufAllocator(boolean preferDirect) {
    this(preferDirect, false);
}

public UnpooledByteBufAllocator(boolean preferDirect, boolean disableLeakDetector) {
    this(preferDirect, disableLeakDetector, PlatformDependent.useDirectBufferNoCleaner() /** 返回 true **/ );
}

/**
 * Create a new instance
 *
 * @param preferDirect {@code true} if {@link #buffer(int)} should try to allocate a direct buffer rather than
 *                     a heap buffer
 * @param disableLeakDetector {@code true} if the leak-detection should be disabled completely for this
 *                            allocator. This can be useful if the user just want to depend on the GC to handle
 *                            direct buffers when not explicit released.
 * @param tryNoCleaner {@code true} if we should try to use {@link PlatformDependent#allocateDirectNoCleaner(int)}
 *                            to allocate direct memory.
 */
public UnpooledByteBufAllocator(boolean preferDirect, boolean disableLeakDetector, boolean tryNoCleaner) {
    super(preferDirect);
    this.disableLeakDetector = disableLeakDetector;
    noCleaner = tryNoCleaner && PlatformDependent.hasUnsafe() /** 返回 true **/
            && PlatformDependent.hasDirectBufferNoCleanerConstructor() /** 返回 true **/ ;
}

newHeapBuffer:

@Override
protected ByteBuf newHeapBuffer(int initialCapacity, int maxCapacity) {
    return PlatformDependent.hasUnsafe() ?
            new InstrumentedUnpooledUnsafeHeapByteBuf(this, initialCapacity, maxCapacity) :
            new InstrumentedUnpooledHeapByteBuf(this, initialCapacity, maxCapacity);
}

newDirectBuffer:

@Override
protected ByteBuf newDirectBuffer(int initialCapacity, int maxCapacity) {
    final ByteBuf buf;
    if (PlatformDependent.hasUnsafe()) {
        buf = noCleaner ? new InstrumentedUnpooledUnsafeNoCleanerDirectByteBuf(this, initialCapacity, maxCapacity) :
                new InstrumentedUnpooledUnsafeDirectByteBuf(this, initialCapacity, maxCapacity);
    } else {
        buf = new InstrumentedUnpooledDirectByteBuf(this, initialCapacity, maxCapacity);
    }
    return disableLeakDetector ? buf : toLeakAwareBuffer(buf);
}

compositeHeapBuffer:

@Override
public CompositeByteBuf compositeHeapBuffer(int maxNumComponents) {
    CompositeByteBuf buf = new CompositeByteBuf(this, false, maxNumComponents);
    return disableLeakDetector ? buf : toLeakAwareBuffer(buf);
}

compositeDirectBuffer

@Override
public CompositeByteBuf compositeDirectBuffer(int maxNumComponents) {
    CompositeByteBuf buf = new CompositeByteBuf(this, true, maxNumComponents);
    return disableLeakDetector ? buf : toLeakAwareBuffer(buf);
}

isDirectBufferPooled:

@Override
public boolean isDirectBufferPooled() {
    return false;
}

Metric 相关操作方法:

@Override
public ByteBufAllocatorMetric metric() {
    return metric;
}

void incrementDirect(int amount) { // 增加 Direct
    metric.directCounter.add(amount);
}
void decrementDirect(int amount) { // 减少 Direct
    metric.directCounter.add(-amount);
}

void incrementHeap(int amount) { // 增加 Heap
    metric.heapCounter.add(amount);
}
void decrementHeap(int amount) { // 减少 Heap
    metric.heapCounter.add(-amount);
}

InstrumentedUnpooledUnsafeHeapByteBuf,在 UnpooledByteBufAllocator 的内部静态类,继承 UnpooledUnsafeHeapByteBuf 类:
在原先的基础上,调用 Metric 相应的增减操作方法,来记录 Heap 占用内存的大小。

private static final class InstrumentedUnpooledUnsafeHeapByteBuf extends UnpooledUnsafeHeapByteBuf {

    InstrumentedUnpooledUnsafeHeapByteBuf(UnpooledByteBufAllocator alloc, int initialCapacity, int maxCapacity) {
        super(alloc, initialCapacity, maxCapacity);
    }

    @Override
    protected byte[] allocateArray(int initialCapacity) {
        byte[] bytes = super.allocateArray(initialCapacity);
        // Metric ++
        ((UnpooledByteBufAllocator) alloc()).incrementHeap(bytes.length);
        return bytes;
    }

    @Override
    protected void freeArray(byte[] array) {
        int length = array.length;
        super.freeArray(array);
        // Metric --
        ((UnpooledByteBufAllocator) alloc()).decrementHeap(length);
    }
}

InstrumentedUnpooledHeapByteBuf ,在 UnpooledByteBufAllocator 的内部静态类,继承 UnpooledHeapByteBuf 类:

private static final class InstrumentedUnpooledHeapByteBuf extends UnpooledHeapByteBuf {

    InstrumentedUnpooledHeapByteBuf(UnpooledByteBufAllocator alloc, int initialCapacity, int maxCapacity) {
        super(alloc, initialCapacity, maxCapacity);
    }

    @Override
    protected byte[] allocateArray(int initialCapacity) {
        byte[] bytes = super.allocateArray(initialCapacity);
        // Metric ++
        ((UnpooledByteBufAllocator) alloc()).incrementHeap(bytes.length);
        return bytes;
    }

    @Override
    protected void freeArray(byte[] array) {
        int length = array.length;
        super.freeArray(array);
        // Metric --
        ((UnpooledByteBufAllocator) alloc()).decrementHeap(length);
    }
//在原先的基础上,调用 Metric 相应的增减操作方法,得以记录 Heap 占用内存的大小。
}

InstrumentedUnpooledUnsafeDirectByteBuf ,在 UnpooledByteBufAllocator 的内部静态类,继承 UnpooledUnsafeDirectByteBuf 类:

private static final class InstrumentedUnpooledUnsafeDirectByteBuf extends UnpooledUnsafeDirectByteBuf {
    InstrumentedUnpooledUnsafeDirectByteBuf(
            UnpooledByteBufAllocator alloc, int initialCapacity, int maxCapacity) {
        super(alloc, initialCapacity, maxCapacity);
    }

    @Override
    protected ByteBuffer allocateDirect(int initialCapacity) {
        ByteBuffer buffer = super.allocateDirect(initialCapacity);
        // Metric ++
        ((UnpooledByteBufAllocator) alloc()).incrementDirect(buffer.capacity());
        return buffer;
    }

    @Override
    protected void freeDirect(ByteBuffer buffer) {
        int capacity = buffer.capacity();
        super.freeDirect(buffer);
        // Metric --
        ((UnpooledByteBufAllocator) alloc()).decrementDirect(capacity);
    }
}

InstrumentedUnpooledDirectByteBuf 的内部静态类,继承 UnpooledDirectByteBuf 类:

private static final class InstrumentedUnpooledDirectByteBuf extends UnpooledDirectByteBuf {

    InstrumentedUnpooledDirectByteBuf(
            UnpooledByteBufAllocator alloc, int initialCapacity, int maxCapacity) {
        super(alloc, initialCapacity, maxCapacity);
    }

    @Override
    protected ByteBuffer allocateDirect(int initialCapacity) {
        ByteBuffer buffer = super.allocateDirect(initialCapacity);
        // Metric ++
        ((UnpooledByteBufAllocator) alloc()).incrementDirect(buffer.capacity());
        return buffer;
    }

    @Override
    protected void freeDirect(ByteBuffer buffer) {
        int capacity = buffer.capacity();
        super.freeDirect(buffer);
        // Metric --
        ((UnpooledByteBufAllocator) alloc()).decrementDirect(capacity);
    }

}

InstrumentedUnpooledDirectByteBuf 的内部静态类,继承 UnpooledUnsafeNoCleanerDirectByteBuf 类:

private static final class InstrumentedUnpooledUnsafeNoCleanerDirectByteBuf
        extends UnpooledUnsafeNoCleanerDirectByteBuf {

    InstrumentedUnpooledUnsafeNoCleanerDirectByteBuf(
            UnpooledByteBufAllocator alloc, int initialCapacity, int maxCapacity) {
        super(alloc, initialCapacity, maxCapacity);
    }

    @Override
    protected ByteBuffer allocateDirect(int initialCapacity) {
        ByteBuffer buffer = super.allocateDirect(initialCapacity);
        // Metric ++
        ((UnpooledByteBufAllocator) alloc()).incrementDirect(buffer.capacity());
        return buffer;
    }

    @Override
    ByteBuffer reallocateDirect(ByteBuffer oldBuffer, int initialCapacity) {
        int capacity = oldBuffer.capacity();
        ByteBuffer buffer = super.reallocateDirect(oldBuffer, initialCapacity);
        // Metric ++
        ((UnpooledByteBufAllocator) alloc()).incrementDirect(buffer.capacity() - capacity);
        return buffer;
    }

    @Override
    protected void freeDirect(ByteBuffer buffer) {
        int capacity = buffer.capacity();
        super.freeDirect(buffer);
        // Metric --
        ((UnpooledByteBufAllocator) alloc()).decrementDirect(capacity);
    }

}

UnpooledUnsafeNoCleanerDirectByteBuf ,继承 UnpooledUnsafeDirectByteBuf 类:

class UnpooledUnsafeNoCleanerDirectByteBuf extends UnpooledUnsafeDirectByteBuf {

    UnpooledUnsafeNoCleanerDirectByteBuf(ByteBufAllocator alloc, int initialCapacity, int maxCapacity) {
        super(alloc, initialCapacity, maxCapacity);
    }

    @Override
    protected ByteBuffer allocateDirect(int initialCapacity) {
        // 反射,直接创建 ByteBuffer 对象。并且该对象不带 Cleaner 对象
        return PlatformDependent.allocateDirectNoCleaner(initialCapacity);
    }

    ByteBuffer reallocateDirect(ByteBuffer oldBuffer, int initialCapacity) {
        return PlatformDependent.reallocateDirectNoCleaner(oldBuffer, initialCapacity);
    }

    @Override
    protected void freeDirect(ByteBuffer buffer) {
        // 直接释放 ByteBuffer 对象
        PlatformDependent.freeDirectNoCleaner(buffer);
    }

    @Override
    public ByteBuf capacity(int newCapacity) {
        checkNewCapacity(newCapacity);

        int oldCapacity = capacity();
        if (newCapacity == oldCapacity) {
            return this;
        }

        // 重新分配 ByteBuf 对象
        ByteBuffer newBuffer = reallocateDirect(buffer, newCapacity);

        if (newCapacity < oldCapacity) {
            if (readerIndex() < newCapacity) {
                // 重置 writerIndex 为 newCapacity ,避免越界
                if (writerIndex() > newCapacity) {
                    writerIndex(newCapacity);
                }
            } else {
                // 重置 writerIndex 和 readerIndex 为 newCapacity ,避免越界
                setIndex(newCapacity, newCapacity);
            }
        }

        // 设置 ByteBuf 对象
        setByteBuffer(newBuffer, false);
        return this;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值