Netty之Buffer(二)ByteBufAllocator

ByteBufAllocatorはByteBufアロケーターであり、ByteBufオブジェクトの作成を担当します。彼には3つの主要なサブクラスがあります。

  1. PreferHeapByteBufAllocator、ヒープByteBufアロケーターを作成する傾向があります。
  2. PooledByteBufAllocator、メモリプールに基づくByteBufのアロケータ。
  3. UnpooledByteBufAllocator、通常のByteBufアロケーター。
    ここでは、まずPreferHeapByteBufAllocatorを確認します。

buffer()メソッドはByteBufオブジェクトを作成します。実装クラスは、ヒープByteBufを作成するか、直接ByteBufを作成するかを決定します。

/**
 * Allocate a {@link ByteBuf}. If it is a direct or heap buffer
 * depends on the actual implementation.
 */
ByteBuf buffer();
ByteBuf buffer(int initialCapacity);
ByteBuf buffer(int initialCapacity, int maxCapacity);

ioBuffer()メソッドは、IO操作用のByteBufオブジェクトを作成します。
IO操作には、パフォーマンスが向上するDirect ByteBufが推奨されます。

/**
 * Allocate a {@link ByteBuf}, preferably a direct buffer which is suitable for I/O.
 */
ByteBuf ioBuffer();
ByteBuf ioBuffer(int initialCapacity);
ByteBuf ioBuffer(int initialCapacity, int maxCapacity);

heapBuffer()メソッドは、ヒープバッファオブジェクトを作成します。

/**
 * Allocate a heap {@link ByteBuf}.
 */
ByteBuf heapBuffer();
ByteBuf heapBuffer(int initialCapacity);
ByteBuf heapBuffer(int initialCapacity, int maxCapacity);

directBuffer()メソッドは、Direct Bufferオブジェクトを作成します。

/**
 * Allocate a direct {@link ByteBuf} with the given initial capacity.
 */
ByteBuf directBuffer(int initialCapacity);
ByteBuf directBuffer(int initialCapacity, int maxCapacity);
CompositeByteBuf compositeBuffer();

compositeBuffer()メソッドは、複合ByteBufオブジェクトを作成します。実装クラスは、Heap ByteBufまたはDirect ByteBufが具体的に作成されるかどうかを決定します。

/**
 * Allocate a {@link CompositeByteBuf}.
 * If it is a direct or heap buffer depends on the actual implementation.
 */
CompositeByteBuf compositeBuffer();
CompositeByteBuf compositeBuffer(int maxNumComponents);

compositeHeapBuffer()メソッドは、Composite Heap ByteBufオブジェクトを作成します。

/**
 * Allocate a heap {@link CompositeByteBuf}.
 */
CompositeByteBuf compositeHeapBuffer();
CompositeByteBuf compositeHeapBuffer(int maxNumComponents);

compositeDirectBuffer(…)メソッドは、Composite Direct ByteBufオブジェクトを作成します。

/**
 * Allocate a direct {@link CompositeByteBuf}.
 */
CompositeByteBuf compositeDirectBuffer();
CompositeByteBuf compositeDirectBuffer(int maxNumComponents);

Direct ByteBufオブジェクトプールに基づくisDirectBufferPooled()メソッド:

/**
 * Returns {@code true} if direct {@link ByteBuf}'s are pooled
 */
boolean isDirectBufferPooled();

calculateNewCapacity(int minNewCapacity、int maxCapacity)メソッドは、ByteBufが拡張されたときに新しい容量を計算します。この容量の値は、[minNewCapacity、maxCapacity]の範囲にあります。

/**
 * Calculate the new capacity of a {@link ByteBuf} that is used when a {@link ByteBuf} needs to expand by the
 * {@code minNewCapacity} with {@code maxCapacity} as upper-bound.
 */
int calculateNewCapacity(int minNewCapacity, int maxCapacity);

ByteBufAllocatorインターフェイスとByteBufAllocator抽象実装クラスを実装するAbstractByteBufAllocatorは、PooledByteBufAllocatorおよびUnpooledByteBufAllocatorのパブリックメソッドを提供します。
工法:

/**
 * 是否倾向创建 Direct ByteBuf
 */
private final boolean directByDefault;
/**
 * 空 ByteBuf 缓存
 */
private final ByteBuf emptyBuf;

/**
 * Instance use heap buffers by default
 */
protected AbstractByteBufAllocator() {
    this(false);
}

/**
 * Create new instance
 *
 * @param preferDirect {@code true} if {@link #buffer(int)} should try to allocate a direct buffer rather than
 *                     a heap buffer
 */
protected AbstractByteBufAllocator(boolean preferDirect) {
    directByDefault = preferDirect && PlatformDependent.hasUnsafe(); // 支持 Unsafe
    emptyBuf = new EmptyByteBuf(this);
}

directByDefault属性:Direct ByteBufを作成するかどうか。安全でない操作をサポートするための前提条件があります。
emptyBufプロパティ:空のByteBufキャッシュオブジェクト。空のByteBufオブジェクトを作成するときにbuffer()などのメソッドに使用されます。

buffer:
directByDefaultの値に応じて、directBuffer()メソッドまたはheapBuffer()メソッドを呼び出します。

@Override
public ByteBuf buffer() {
    if (directByDefault) {
        return directBuffer();
    }
    return heapBuffer();
}
@Override
public ByteBuf buffer(int initialCapacity) {
    if (directByDefault) {
        return directBuffer(initialCapacity);
    }
    return heapBuffer(initialCapacity);
}
@Override
public ByteBuf buffer(int initialCapacity, int maxCapacity) {
    if (directByDefault) {
        return directBuffer(initialCapacity, maxCapacity);
    }
    return heapBuffer(initialCapacity, maxCapacity);
}

ioBuffer:
Unsafe操作がサポートされているかどうかに応じて、directBuffer()メソッドまたはheapBuffer()メソッドを呼び出します。

/**
 * 默认容量大小
 */
static final int DEFAULT_INITIAL_CAPACITY = 256;

@Override
public ByteBuf ioBuffer() {
    if (PlatformDependent.hasUnsafe()) {
        return directBuffer(DEFAULT_INITIAL_CAPACITY);
    }
    return heapBuffer(DEFAULT_INITIAL_CAPACITY);
}

@Override
public ByteBuf ioBuffer(int initialCapacity) {
    if (PlatformDependent.hasUnsafe()) {
        return directBuffer(initialCapacity);
    }
    return heapBuffer(initialCapacity);
}

@Override
public ByteBuf ioBuffer(int initialCapacity, int maxCapacity) {
    if (PlatformDependent.hasUnsafe()) {
        return directBuffer(initialCapacity, maxCapacity);
    }
    return heapBuffer(initialCapacity, maxCapacity);
}

heapBuffer

/**
 * 默认最大容量大小,无限。
 */
static final int DEFAULT_MAX_CAPACITY = Integer.MAX_VALUE;

@Override
public ByteBuf heapBuffer() {
    return heapBuffer(DEFAULT_INITIAL_CAPACITY, DEFAULT_MAX_CAPACITY);
}

@Override
public ByteBuf heapBuffer(int initialCapacity) {
    return heapBuffer(initialCapacity, DEFAULT_MAX_CAPACITY);
}

@Override
public ByteBuf heapBuffer(int initialCapacity, int maxCapacity) {
    // 空 ByteBuf 对象
    if (initialCapacity == 0 && maxCapacity == 0) {
        return emptyBuf;
    }
    validate(initialCapacity, maxCapacity); // 校验容量的参数
    // 创建 Heap ByteBuf 对象
    return newHeapBuffer(initialCapacity, maxCapacity);
}

最後に、newHeapBuffer(int initialCapacity、int maxCapacity)抽象メソッドを呼び出して、ヒープByteBufオブジェクトを作成します。Heap ByteBufオブジェクトを作成する実装は、オブジェクトプーリングの方法によって異なるため、抽象化が必要です。

/**
 * Create a heap {@link ByteBuf} with the given initialCapacity and maxCapacity.
 */
protected abstract ByteBuf newHeapBuffer(int initialCapacity, int maxCapacity);

directBuffer:

@Override
public ByteBuf directBuffer() {
    return directBuffer(DEFAULT_INITIAL_CAPACITY, DEFAULT_MAX_CAPACITY);
}

@Override
public ByteBuf directBuffer(int initialCapacity) {
    return directBuffer(initialCapacity, DEFAULT_MAX_CAPACITY);
}

@Override
public ByteBuf directBuffer(int initialCapacity, int maxCapacity) {
    // 空 ByteBuf 对象
    if (initialCapacity == 0 && maxCapacity == 0) {
        return emptyBuf;
    }
    validate(initialCapacity, maxCapacity); // 校验容量的参数
    // 创建 Direct ByteBuf 对象
    return newDirectBuffer(initialCapacity, maxCapacity);
}

最後に、newDirectBuffer(int initialCapacity、int maxCapacity)抽象メソッドが呼び出されて、Direct ByteBufオブジェクトが作成されます。DirectByteBufオブジェクトの作成の実装は、オブジェクトプールの方法に基づいて異なるため、抽象化が必要です。

/**
 * Create a direct {@link ByteBuf} with the given initialCapacity and maxCapacity.
 */
protected abstract ByteBuf newDirectBuffer(int initialCapacity, int maxCapacity);

compositeBufferは、directByDefaultの値に従って、compositeDirectBuffer()メソッドまたはcompositeHeapBuffer()メソッドを呼び出します。

@Override
public CompositeByteBuf compositeBuffer() {
    if (directByDefault) {
        return compositeDirectBuffer();
    }
    return compositeHeapBuffer();
}

@Override
public CompositeByteBuf compositeBuffer(int maxNumComponents) {
    if (directByDefault) {
        return compositeDirectBuffer(maxNumComponents);
    }
    return compositeHeapBuffer(maxNumComponents);
}

compositeHeapBuffer、CompositeByteBufオブジェクトを作成し、メソッドパラメータdirectはfalseで、ヒープタイプを示します。toLeakAwareBuffer(CompositeByteBuf)メソッドを呼び出して、LeakAware ByteBufオブジェクトを装飾します。

/**
 * Composite ByteBuf 可包含的 ByteBuf 的最大数量
 */
static final int DEFAULT_MAX_COMPONENTS = 16;

@Override
public CompositeByteBuf compositeHeapBuffer() {
    return compositeHeapBuffer(DEFAULT_MAX_COMPONENTS);
}

@Override
public CompositeByteBuf compositeHeapBuffer(int maxNumComponents) {
    return toLeakAwareBuffer(new CompositeByteBuf(this, false, maxNumComponents));
}

compositeDirectBuffer:

@Override
public CompositeByteBuf compositeDirectBuffer() {
    return compositeDirectBuffer(DEFAULT_MAX_COMPONENTS);
}

@Override
public CompositeByteBuf compositeDirectBuffer(int maxNumComponents) {
    return toLeakAwareBuffer(new CompositeByteBuf(this, true, maxNumComponents));
}

CompositeByteBufオブジェクトを作成します。メソッドパラメータdirectはtrueで、Directタイプを示します。
toLeakAwareBuffer(CompositeByteBuf)メソッドを呼び出して、LeakAware ByteBufオブジェクトを装飾します。
calculateNewCapacity:

/**
 * 扩容分界线,4M
 */
static final int CALCULATE_THRESHOLD = 1048576 * 4; // 4 MiB page

 @Override
 public int calculateNewCapacity(int minNewCapacity, int maxCapacity) {
     if (minNewCapacity < 0) {
         throw new IllegalArgumentException("minNewCapacity: " + minNewCapacity + " (expected: 0+)");
     }
     if (minNewCapacity > maxCapacity) {
         throw new IllegalArgumentException(String.format(
                 "minNewCapacity: %d (expected: not greater than maxCapacity(%d)",
                 minNewCapacity, maxCapacity));
     }
     final int threshold = CALCULATE_THRESHOLD; // 4 MiB page
 
     //  等于 threshold ,直接返回 threshold 。
     if (minNewCapacity == threshold) {
         return threshold;
     }
 
     //  超过 threshold ,增加 threshold ,不超过 maxCapacity 大小。
     // If over threshold, do not double but just increase by threshold.
     if (minNewCapacity > threshold) {
         int newCapacity = minNewCapacity / threshold * threshold;
         if (newCapacity > maxCapacity - threshold) { // 不超过 maxCapacity
             newCapacity = maxCapacity;
         } else {
             newCapacity += threshold;
         }
         return newCapacity;
     }
 
     //  未超过 threshold ,从 64 开始两倍计算,不超过 4M 大小。
     // Not over threshold. Double up to 4 MiB, starting from 64.
     int newCapacity = 64;
     while (newCapacity < minNewCapacity) {
         newCapacity <<= 1;
     }
     return Math.min(newCapacity, maxCapacity);
 }

ByteBufAllocatorインターフェースを実装するPreferHeapByteBufAllocatorは、ヒープByteBufアロケーターを作成する傾向があります。したがって、buffer()およびioBuffer()およびcompositeBuffer()メソッドは、ヒープByteBufオブジェクトを作成します。

/**
 * 真正的分配器对象
 */
private final ByteBufAllocator allocator;

public PreferHeapByteBufAllocator(ByteBufAllocator allocator) {
    this.allocator = ObjectUtil.checkNotNull(allocator, "allocator");
}

@Override
public ByteBuf buffer() {
    return allocator.heapBuffer();
}

@Override
public ByteBuf ioBuffer() {
    return allocator.heapBuffer();
}

@Override
public CompositeByteBuf compositeBuffer() {
    return allocator.compositeHeapBuffer();
}
公開された46元の記事 ウォンの賞賛6 ビュー3847

おすすめ

転載: blog.csdn.net/weixin_43257196/article/details/105033635