ByteBuf是做什麼用的?Netty中傳遞位元組資料的容器。
ByteBuf的使用模式有那些?
使用模式 | 描述 | 優點 | 劣勢 |
---|---|---|---|
堆緩衝區 | 資料存儲存在JVM的堆空間中,又稱為支撐陣列,通過 hasArray 來判斷是不是在堆緩衝區中 | 沒使用池化情況下能提供快速的分配和釋放 | 傳送之前都會拷貝到直接緩衝區 |
直接緩衝區 | 儲存在實體記憶體中 |
|
|
複合緩衝 | 單個緩衝區合併多個緩衝區表示 | 操作多個更方便 | – |
ByteBuf如何訪問?
- 下標訪問:get,set開頭的相關方法,不修改索引
- 索引訪問:read,write開頭的方法,根據已經訪問過的位元組對索引進行調整[索引是ByteBuf內建的readIndex和writeIndex]
ByteBuf本身有一定的容量限制,預設最大的是Integer.MAX_VALUE,超出範圍拋IndeOutOfBoundsException
ByteBuf索引操作是怎樣?
兩個索引將ByteBuf分隔成3個區域
任何新分配的、包裝的或者複製的預設大小readerIndex/writeIndex都是0,任何read或者skip開頭的都會增加readerIndex已讀位元組數,write開頭的操作則會增加writeIndex相應位元組數。另外引數中包含ByteBuf且沒有目標索引的[比如 readBytes(ByteBuf dest) writeBytes(ByteBuf dest)],會影響對應的readerIndex(寫的方法影響readerIndex)writeIndex(讀的方法影響writeIndex)。
呼叫discardReadBytes()會移動可讀位元組到下標0,可讀位元組平移(原來可讀位元組的內容沒有做擦除,只是移動了writeIndex)
呼叫clear()方法,則僅重置索引,使得readIndex和writeIndex為0,不做任何記憶體複製
ByteBuf的派生緩衝區是什麼?
ByteBuf專門呈現內容檢視的方法,它們返回新的ByteBuf例項有自己的索引,但是內部儲存共享,即它的內容修改了源例項也會改變。方法比如 slice / Unpooled.unmodifiableBuffer / order / readSlice / duplicate 。
需要完全獨立的副本則選擇使用 copy
ByteBuf有沒有其它方式來管理例項?
- ByteBufAllocator:使用ChannelHandleContext(Channel每個都有不同的例項,或者ChannelHandler獲取)能夠拿到它的引用,Netty從4.1.x開始預設使用池化(PooledByteBufAllocator)實現,能最大程度的減少記憶體碎片,另外一種方式是非池化(UnpooledByteBufAllocator)每次返回一個新例項;
- Unpooled:一個工具類,提供靜態方法建立未池化的ByteBuf
- ByteBufUtil:實現一些使用的方法,比如equals判斷兩個ByteBuf是不是相等,hexdump以十六進位制列印ByteBuf內容