Netty中的ByteBuf詳解

爬蜥發表於2018-05-03

ByteBuf是做什麼用的?Netty中傳遞位元組資料的容器。

ByteBuf的使用模式有那些?

使用模式 描述 優點 劣勢
堆緩衝區 資料存儲存在JVM的堆空間中,又稱為支撐陣列,通過 hasArray 來判斷是不是在堆緩衝區中 沒使用池化情況下能提供快速的分配和釋放 傳送之前都會拷貝到直接緩衝區
直接緩衝區 儲存在實體記憶體中
  • 能獲取超過jvm堆限制大小的空間
  • 寫入channel比堆緩衝區更快
  • 釋放和分配空間昂貴(使用系統的方法)
  • 操作時需要複製一次到堆上
複合緩衝 單個緩衝區合併多個緩衝區表示 操作多個更方便

ByteBuf如何訪問?

  1. 下標訪問:get,set開頭的相關方法,不修改索引
  2. 索引訪問: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)

Netty中的ByteBuf詳解

呼叫clear()方法,則僅重置索引,使得readIndex和writeIndex為0,不做任何記憶體複製

Netty中的ByteBuf詳解

ByteBuf的派生緩衝區是什麼?

ByteBuf專門呈現內容檢視的方法,它們返回新的ByteBuf例項有自己的索引,但是內部儲存共享,即它的內容修改了源例項也會改變。方法比如 slice / Unpooled.unmodifiableBuffer / order / readSlice / duplicate 。

需要完全獨立的副本則選擇使用 copy

ByteBuf有沒有其它方式來管理例項?

  1. ByteBufAllocator:使用ChannelHandleContext(Channel每個都有不同的例項,或者ChannelHandler獲取)能夠拿到它的引用,Netty從4.1.x開始預設使用池化(PooledByteBufAllocator)實現,能最大程度的減少記憶體碎片,另外一種方式是非池化(UnpooledByteBufAllocator)每次返回一個新例項;
  2. Unpooled:一個工具類,提供靜態方法建立未池化的ByteBuf
  3. ByteBufUtil:實現一些使用的方法,比如equals判斷兩個ByteBuf是不是相等,hexdump以十六進位制列印ByteBuf內容

來源:https://juejin.im/post/5aeb1de46fb9a07ac3635137

相關文章