Netty整理(三)
阿新 • • 發佈:2019-10-09
ByteBuf:是資料容器(位元組容器)
JDK ByteBuffer
共用讀寫索引,每次讀寫操作都需要Flip()
擴容麻煩,而且擴容後容易造成浪費 關於ByteBuffer的使用方法可以參考序列化和反序列化的三種方法 ,裡面有Netty 3的ChannelBuffer,因為現在Netty 3用的比較少,當作參考就好。
Netty ByteBuf
讀寫使用不同的索引,所以操作便捷
自動擴容,使用便捷
我們現在來看一下ByteBuf的原始碼。
public abstract class ByteBuf implements ReferenceCounted, Comparable<ByteBuf>
我們可以看到ByteBuf是一個抽象類,它裡面幾乎大部分都是抽象方法。
繼承ByteBuf的是一個AbstractByteBuf的抽象類,而讀寫索引的屬性就在該類中。
public abstract class AbstractByteBuf extends ByteBuf
int readerIndex; //讀索引 int writerIndex; //寫索引 private int markedReaderIndex; //標記當前讀索引的位置 private int markedWriterIndex; //標記當前寫索引的位置 private int maxCapacity; //最大容量
而支援自動擴容的部分可以由ensureWritable追蹤看到
@Override public ByteBuf ensureWritable(int minWritableBytes) { if (minWritableBytes < 0) { throw new IllegalArgumentException(String.format( "minWritableBytes: %d (expected: >= 0)", minWritableBytes)); } ensureWritable0(minWritableBytes); return this; } final void ensureWritable0(int minWritableBytes) { ensureAccessible(); if (minWritableBytes <= writableBytes()) { return; } if (minWritableBytes > maxCapacity - writerIndex) { throw new IndexOutOfBoundsException(String.format( "writerIndex(%d) + minWritableBytes(%d) exceeds maxCapacity(%d): %s", writerIndex, minWritableBytes, maxCapacity, this)); } // Normalize the current capacity to the power of 2. int newCapacity = alloc().calculateNewCapacity(writerIndex + minWritableBytes, maxCapacity); // Adjust to the new capacity. capacity(newCapacity); }
在AbstractByteBufAllocator中
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 if (minNewCapacity == threshold) { return threshold; } // If over threshold, do not double but just increase by threshold. if (minNewCapacity > threshold) { int newCapacity = minNewCapacity / threshold * threshold; if (newCapacity > maxCapacity - threshold) { newCapacity = maxCapacity; } else { newCapacity += threshold; } return newCapacity; } // Not over threshold. Double up to 4 MiB, starting from 64. int newCapacity = 64; while (newCapacity < minNewCapacity) { newCapacity <<= 1; } return Math.min(newCapacity, maxCapacity); }
這個newCapacity就是擴容的新容量,所以我們一般不需要擔心ByteBuf容