關於JDK中的ByteBuffer與Netty中的ByteBuf的對比

JDK中ByteBuffer的缺點

  1. 只是用一個標誌位position來進行讀寫標記,讀寫操作要使用flip方法進行切換,不太友好。
  2. 因爲ByteBuffer中的實際存儲數據的數組是使用final修飾符修飾的,所以不可以 在原來buffer的基礎上動態擴容或者縮小。如果需要擴容,需要另外新建一個ByteBuffer,並將舊的ByteBuffer裏面的數組複製到已經擴容的ByteBuffer.
     final byte[] hb;

Netty中的ByteBuf則完全對JDK中的ByteBuffer的缺點進行了改進

  1. 使用readerIndex和writerIndex分別維護讀操作和寫操作,實現讀寫索引分離,更加直觀。
    byte[] array;
  2. ByteBuf使用的底層數據維護數組沒有使用final關鍵字,所以存在直接在原來ByteBuf進行擴容的可能,而這件事,Betty已經爲我們完成,封裝在它的write系列方法當中。但是它也存在着一個上限,這個上限就是Integer.MAX_VALUE.
        public ByteBuf writeByte(int value) {
            ensureWritable0(1);//用於驗證可寫字節長度是否大於將要寫入的字節長度。
            _setByte(writerIndex++, value);//寫入一個字節並且索引加一的操作。
            return this;
        }
        final void ensureWritable0(int minWritableBytes) {
            ensureAccessible();//驗證ByteBuf中的引用計數是否爲零,爲真則拋出異常,違背了Netty對於垃圾回收的約定
            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);//計算擴容後capacity
            //擴容的當前capactiy的兩倍。
            // Adjust to the new capacity.
            capacity(newCapacity);//重新設置capactiy.並進行數組的重新拷貝
        }

        public ByteBuf capacity(int newCapacity) {
            checkNewCapacity(newCapacity);//驗證新生成的capacity是否大於最大整數,是則拋出異常
    
            int oldCapacity = array.length;
            byte[] oldArray = array;
            if (newCapacity > oldCapacity) {
                byte[] newArray = allocateArray(newCapacity);//新建一個新的數組,數組長度爲新創建capacity
                System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);//進行舊數組中的數組拷貝到新數組中
                setArray(newArray);//將當前buffer中的array指向新數組
                freeArray(oldArray);//釋放掉舊數組
            } else if (newCapacity < oldCapacity) {
                byte[] newArray = allocateArray(newCapacity);
                int readerIndex = readerIndex();
                if (readerIndex < newCapacity) {
                    int writerIndex = writerIndex();
                    if (writerIndex > newCapacity) {
                        writerIndex(writerIndex = newCapacity);
                    }
                    System.arraycopy(oldArray, readerIndex, newArray, readerIndex, writerIndex - readerIndex);
                } else {
                    setIndex(newCapacity, newCapacity);
                }
                setArray(newArray);
                freeArray(oldArray);
            }
            return this;
        }



發佈了89 篇原創文章 · 獲贊 12 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章