ByteBufAllocatorはByteBufアロケーターであり、ByteBufオブジェクトの作成を担当します。彼には3つの主要なサブクラスがあります。
- PreferHeapByteBufAllocator、ヒープByteBufアロケーターを作成する傾向があります。
- PooledByteBufAllocator、メモリプールに基づくByteBufのアロケータ。
- 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();
}