堆緩衝區
ByteBuf heapBuf = ...;
if (heapBuf.hasArray()) {
byte[] array = heapBuf.array();
int offset = heapBuf.arrayOffset() + heapBuf.readerIndex();
int length = heapBuf.readableBytes();
handleArray(array, offset, length);
}
跟蹤UnpooledHeapByteBuf源碼,很顯然是數組方式實現
byte[] array;
public byte[] array() {
this.ensureAccessible();
return this.array;
}
public int arrayOffset() {
return 0;
}
初始化的部分
public UnpooledHeapByteBuf(ByteBufAllocator alloc, int initialCapacity, int maxCapacity) {
……
this.setArray(this.allocateArray(initialCapacity));
……
}
byte[] allocateArray(int initialCapacity) {
return new byte[initialCapacity];
}
容量變化
public ByteBuf capacity(int newCapacity) {
this.checkNewCapacity(newCapacity);
int oldCapacity = this.array.length;
byte[] oldArray = this.array;
byte[] newArray;
if (newCapacity > oldCapacity) {
newArray = this.allocateArray(newCapacity);
System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);
this.setArray(newArray);
this.freeArray(oldArray);
} else if (newCapacity < oldCapacity) {
newArray = this.allocateArray(newCapacity);
int readerIndex = this.readerIndex();
if (readerIndex < newCapacity) {
int writerIndex = this.writerIndex();
if (writerIndex > newCapacity) {
writerIndex = newCapacity;
this.writerIndex(newCapacity);
}
System.arraycopy(oldArray, readerIndex, newArray, readerIndex, writerIndex - readerIndex);
} else {
this.setIndex(newCapacity, newCapacity);
}
this.setArray(newArray);
this.freeArray(oldArray);
}
return this;
}
其中的邏輯,不會去對數組重新做整理,0到readerIndex之間的數據,可能存在其他的引用。
正常的擴容和縮容非常簡單,我們看一下無法進行縮容的情況,是直接讀寫指針設最大,不允許讀寫。
else if (newCapacity < oldCapacity) {
if (readerIndex < newCapacity) {
} else {
this.setIndex(newCapacity, newCapacity);
}
}
再看PooledHeapByteBuf
private final Handle<PooledByteBuf<T>> recyclerHandle;
關鍵部分是多了一個池的管理,其中是採用Stack+WeakOrderQueue數據結構實現的,避免了多線程下取數據時可能出現的線程安全問題,參考
https://blog.csdn.net/alex_xfboy/article/details/90384332