ByteBuf

目錄

1.ByteBuf類

1.1 ByteBuf的工作原理

1.2 ByteBuf的使用模式

2.ByteBuf實例

2.1 ByteBufAllocator

2.2 Unpooled緩衝區

2.3 ByteBufUtil類

3.小結


我們知道,網絡數據的基本單位總是字節。Java NIO提供了ByteBuffer作爲它的字節容器,但是這個類使用起來相當複雜複雜繁瑣。

Netty的ByteBuffer替代品是ByteBuf,即解決了JDK API的侷限性,又爲網絡應用程序的開發者提供了更好的API。

1.ByteBuf類

因爲所有的網絡通信都涉及到字節序列的移動,所以高效易用的數據結構明顯是必不可少的。ByteBuf實現並超越了這些需求。

1.1 ByteBuf的工作原理

ByteBuf維護了兩個不同的索引:一個用於讀取,一個用於寫入。當你從ByteBuf讀取時,它的readerIndex將會被遞增已經被讀取的字節數。同樣地,當你寫入ByteBuf時,它的writerIndex也會被遞增。

當讀取字節直到readerIndex達到和writerIndex同樣的值時,此時readerIndex到達“可以讀取”數據的末尾,繼續讀取的話就會觸發IndexOutOfBoundsException。

名稱以read或者write開頭的ByteBuf方法,將會推進其對應的索引,而名稱以set或者get開頭的操作則不會。ByteBuf的最大容量默認值是Integer.MAX_VALUE,當然我們也可以自定義容量,試圖移動寫索引(即writerIndex)超過這個值將會觸發異常。

1.2 ByteBuf的使用模式

在使用Netty時,有幾種常見的圍繞ByteBuf而構建的使用模式:

  1. 堆緩衝區:將數據存儲在JVM的堆空間中,GC可以及時的釋放內存空間

  2. 直接緩衝區:避免在每次調用本地IO之前或之後,將緩衝區的內容複製到一箇中間緩衝區,實現零拷貝。因爲直接緩衝區駐留在垃圾回收掃描的堆區之外,因此需要手動管理內存。

  3. 複合緩衝區:可以創建多個不同的ByteBuf,然後提供一個這些ByteBuf的組合視圖;複合緩衝區類似一個列表,我們可以動態的添加刪除其中的ByteBuf。這是Netty中獨有的功能,JDK中沒有提供。

關於直接緩衝區和非直接緩衝區的理解可以參考文章:https://www.cnblogs.com/zxrxzw/p/11075951.html

ByteBuf提供了對字節的讀寫、查找、刪除等操作,相關API參考官方API文檔:https://netty.io/4.1/api/index.html

2.ByteBuf實例

2.1 ByteBufAllocator

 爲了降低分配和釋放內存的開銷,Netty通過ByteBufAllocator實現了(ByteBuf)池化,它可以用來分配我們所描述過的任意類型的ByteBuf。ByteBufAllocator常用的方法如下:

  • buffer()\buffer(int initialCapacity)\buffer(int initialCapacity,int maxCapacity):返回一個基於堆或者直接內存存儲的ByteBuf。
  • heapBuffer()\heapBuffer(int initialCapacity)\heapBuffer(int initialCapacity,int maxCapacity):返回一個基於堆內存存儲的ByteBuf。
  • directBuffer()\directBuffer(int initialCapacity)\directBuffer(int initialCapacity,int maxCapacity):返回一個基於直接內存存儲的ByteBuf。
  • compositeBuffer()\compositeBuffer(int maxNumComponents)\compositeDirectBuffer()\compositeDirectBuffer(int maxNumComponents)\compositeHeapBuffer()\compositeHeapBuffer(int maxNumComponents):返回一個可以通過添加最大到指定數目的基於堆的或者直接內存存儲的緩衝區來擴展的CompositeByteBuf。

Netty提供了兩種ByteBufAllocator的實現:PooledByteBufAllocator和UnpooledByteBufAllocator。PooledByteBufAllocator池化了ByteBuf的實例以提高性能並最大限度的減少內存碎片,它採用了jemalloc一種已被大量現代操作系統所採用的高效方法來分配內存,是Netty的默認實現。UnpooledByteBufAllocator實現不池化ByteBuf實例,並且在每次它被調用時都會返回一個新的實例。

2.2 Unpooled緩衝區

Unpooled是Netty提供的一個簡單的工具類,它提供了靜態的輔助方法來創建未池化的ByteBuf實例。相關實現方法如下:

  • buffer()\buffer(int initialCapacity)\buffer(int initialCapacity,int maxCapacity):返回一個基於堆內存存儲的ByteBuf。
  • directBuffer()\directBuffer(int initialCapacity)\directBuffer(int initialCapacity,int maxCapacity):返回一個未池化的基於直接內存存儲的ByteBuf。
  • wrappedBuffer():返回一個包裝了給定數據的ByteBuf
  • copiedBuffer():返回一個複製了給定數據的ByteBuf

2.3 ByteBufUtil類

ByteBufUtil提供了用於操作ByteBuf的靜態的輔助方法,我們可以使用該工具類對ByteBuf進行處理。

3.小結

本章主要討論了Netty的基於ByteBuf的數據容器。我們首先解釋了ByteBuf相對於JDK所提供的實現的優勢,以及相關API,最後指出了它們各自的最佳適用的特定用例。

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