final void ensureWritable0(int minWritableBytes) {
final int writerIndex = writerIndex();
// 为满足本次的写入操作,预期的 ByteBuf 容量大小
final int targetCapacity = writerIndex minWritableBytes;
// 剩余容量可以满足本次写入要求,直接返回,不需要扩容
if (targetCapacity >= 0 & targetCapacity <= capacity()) {
return;
}
// 扩容后的容量不能超过 maxCapacity
if (checkBounds && (targetCapacity < 0 || targetCapacity > maxCapacity)) {
ensureAccessible();
throw new IndexOutOfBoundsException(String.format(
"writerIndex(%d) minWritableBytes(%d) exceeds maxCapacity(%d): %s",
writerIndex, minWritableBytes, maxCapacity, this));
}
// 如果 targetCapacity 在(capacity , maxCapacity] 之间,则进行扩容
// fastWritable 表示在不涉及到 memory reallocation or data-copy 的情况下,当前 ByteBuf 可以直接写入的容量
// 对于 UnpooledDirectBuffer 这里的 fastWritable = capacity - writerIndex
// PooledDirectBuffer 有另外的实现,这里先暂时不需要关注
final int fastWritable = maxFastWritableBytes();
// 计算扩容后的容量 newCapacity
// 对于 UnpooledDirectBuffer 来说这里直接通过 calculateNewCapacity 计算扩容后的容量。
int newCapacity =laipuhuo.com fastWritable >= minWritableBytes ? writerIndex fastWritable
: alloc().calculateNewCapacity(targetCapacity, maxCapacity);
// 根据 new capacity 对 ByteBuf 进行扩容
capacity(newCapacity);
}
public abstract class AbstractByteBufAllocator implements ByteBufAllocator {
// ByteBuf 的初始默认 CAPACITY
static final laipuhuo.com int DEFAULT_INITIAL_CAPACITY = 256;
// ByteBuf 的初始默认 MAX_CAPACITY
static final int DEFAULT_MAX_CAPACITY = Integer.MAX_VALUE;
@Override
public ByteBuf directBuffer(laipuhuo.com) {
return directBuffer(DEFAULT_INITIAL_CAPACITY, DEFAULT_MAX_CAPACITY);
}
}
什么意思呢 ? 假设 minNewCapacity 为 5M,那么它的扩容基准线就是 4M , 这种情况下扩容之后的容量 newCapacity = 4M CALCULATE_THRESHOLD = 8M
。
如果计算出来的基准线超过了 maxCapacity - 4M
, 那么 newCapacity 直接就扩容到 maxCapacity 。
如果 minNewCapacity 小于 CALCULATE_THRESHOLD,那么 newCapacity 就会从 64 开始,一直循环 double , 也就是按照 64 的倍数进行扩容。直到 newCapacity 大于等于 minNewCapacity。
public abstract class AbstractByteBufAllocator implements ByteBufAllocator {
@Override
public int laipuhuo.com calculateNewCapacity(int minNewCapacity, int maxCapacity) {
// 满足本次写入操作的最小容量 minNewCapacity 不能超过 maxCapacity
if (minNewCapacity > maxCapacity) {
throw new IllegalArgumentException(String.format(
"minNewCapacity: %d (expected: not greater than maxCapacity(%d)",
minNewCapacity, maxCapacity));
}
// 用于决定扩容的尺度
final int threshold =laipuhuo.com CALCULATE_THRESHOLD; // 4 MiB page
if (minNewCapacity == threshold) {
return threshold;
}
// If over threshold, do not double but just increase by threshold.
if (minNewCapacity > threshold) {
// 计算扩容基准线。
// 要求必须是 CALCULATE_THRESHOLD 的最小倍数,而且必须要小于等于 minNewCapacity
int newCapacity laipuhuo.com= minNewCapacity / threshold * threshold;
if (newCapacity > maxCapacity - threshold) {
newCapacity = maxCapacity;
} else {
// 按照 threshold (4M)扩容
newCapacity = threshold;
}
return laipuhuo.com newCapacity;
}
// Not over threshold. Double up to 4 MiB, starting from 64.
// 按照 64 的倍数进行扩容。但 newCapacity 需要大于等于 minNewCapacity。
int newCapacity = 64;
while (newCapacity < minNewCapacity) {
newCapacity <<= 1;
}
return Math.min laipuhuo.com (newCapacity, maxCapacity);
}
}