堆缓冲区
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