Netty學習筆記之ByteBuf概覽

1、ByteBuflinux

下圖是ByteBuf的繼承體系:後端

1、分類api

1)從內存分配角度看,可分爲兩種:網絡

(1)堆內存字節緩衝區:如上圖中帶有Heap的類,它們的特色是直接在堆中分配內存,分配和回收快,但缺點是在網絡通訊讀寫中,需額外作一次內存分配,函數

(2)直接內存緩衝區:使用直接內存進行內存分配,如上圖中帶有Direct的類,它們的特色是分配回收較慢,但網絡通訊中不須要進行額外的內存分配,相似於linux中的sendfile系統調用,它直接將內核緩衝區的數據複製到Channel中,再也不通過用戶緩衝區,由於少了一次複製,性能有所提高。性能

在實際使用中的最佳實踐是在I/O通訊線程的讀寫緩衝區使用直接內存緩衝區,後端業務消息的編解碼使用堆內存緩衝區。線程

2)從內存回收角度看,可分爲兩類:指針

(1)基於對象池的ByteBuf:如繼承體系中帶有Pool的類,它們的內存管理基於對象池,它們本身維護了一個內存池,可提高使用效率。對象

(2)普通ByteBuf繼承

基於對象池的ByteBuf使用時須要更加謹慎。

2ByteBuf簡介

1ByteBufByteBuffer的比較

ByteBuf是對NIO中ByteBuffer的封裝,爲何不使用原始的ByteBuffer呢?究其緣由,ByteBuffer有如下不足:

(1):長度固定,一旦分配完成,則容量不能動態擴展或收縮;

(2):讀寫後不方便,由於每次都須要調用flip()等函數處理;

(3):API功能有限,一些高級和實用特性不支持。

2ByteBuf使用

建立ByteBuf的官方推薦方法是使用Unpool來建立,如:

ByteBuf buf = Unpooled.buffer(20);

        相似於ByteBuffer,ByteBuf中也有讀寫索引等概念,不一樣在於ByteBuffer使用一個位置指針處理讀寫操做,而ByteBuffer使用兩個位置指針分別對讀寫進行操做,下圖是ByteBuf的讀寫索引構造:

        其中readerIndex標識讀取索引,writerIndex標識寫索引,capacity爲容量,即readerIndex到writerIndex部分是可讀部分,writerIndex到capacity部分是可寫部分。

        discardable bytes部分是可重用部分,這時咱們可調用相應的api重用該部份內存來增長可寫內存,如調用discardReadBytes()方法則會將writerIndex置爲writerIndex – readerIndex,readerIndex置爲0,同時發生數據的複製,即將原來可讀的內容向前移動,因此頻繁調用該函數將致使性能的降低。下圖是調用discardReadBytes先後的對比圖:

 

        一種更好的方法是調用clear()函數,這樣不會致使內存的移動,它僅僅是移動了位置指針,不過會致使可讀內容的晴空,下圖是調用clear函數先後的狀況:

       ByteBuf中也一樣支持ByteBuffer中的mark和reset操做,不過更加豐富,它支持如下四個函數:

1markReaderIndex

2markWriterIndex

3resetReaderIndex

4resetWriterIndex

 

        ByteBuf中有Derived buffer的概念,ByteBuf提供了接口用於實現ByteBuf的複製,如如下方法:

(1)duplicate:返回當前ByteBuf的複製對象,但返回的ByteBuf對象與原始的ByteBuf共享緩衝區內容,即更改返回後ByteBuf的內容一樣也會更改原始的ByteBuf中的內容,返回後的ByteBuf會維護本身獨立的讀寫索引;

(2)copy:複製一個新的ByteBuf,與duplicate不一樣的是,返回後的ByteBuf在內容上是獨立的。還有copy(int index, int length),從字面上也很好理解;

(3)slice:返回當前ByteBuf的可讀子緩衝區,起始位置從readerIndex到writerIndex,返回後的ByteBuf與原ByteBuf共享內容,但讀寫索引地理維護。

 

        ByteBuf還可轉換成標準的ByteBuffer,主要使用兩個方法:

nioBuffer():將當前ByteBuf的可讀緩衝區轉換成ByteBuffer,但二者共享同一緩衝區內容。

nioBuffer(int index, int length):將當前ByteBufindex開始長度爲length的緩衝區轉換成ByteBuffer

 

        ByteBuf支持一系列的隨機讀寫操做,它們是一系列set和get操做,具體見API。

相關文章
相關標籤/搜索