netty之ByteBuf(堆緩衝區)

堆緩衝區

	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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章