看過英文的文檔源碼,仍是勉強解釋下,分享 數組
ChannelBuffer的實現類有多個,這裏列舉其中主要的幾個: 網絡
1)HeapChannelBuffer:這是Netty讀網絡數據時默認使用的ChannelBuffer,這裏的Heap就是Java堆的意 思,由於 讀SocketChannel的數據是要通過ByteBuffer的,而ByteBuffer實際操做的就是個byte數組,因此 ChannelBuffer的內部就包含了一個byte數組,使得ByteBuffer和ChannelBuffer之間的轉換是零拷貝方式。根據網絡字 節續的不一樣,HeapChannelBuffer又分爲BigEndianHeapChannelBuffer和 LittleEndianHeapChannelBuffer,默認使用的是BigEndianHeapChannelBuffer。Netty在讀網絡 數據時使用的就是HeapChannelBuffer,HeapChannelBuffer是個大小固定的buffer,爲了避免至於分配的Buffer的 大小不太合適,Netty在分配Buffer時會參考上次請求須要的大小。 多線程
2)DynamicChannelBuffer:相比於HeapChannelBuffer,DynamicChannelBuffer可動態自適 應大 小。對於在DecodeHandler中的寫數據操做,在數據大小未知的狀況下,一般使用DynamicChannelBuffer。 socket
3)ByteBufferBackedChannelBuffer:這是directBuffer,直接封裝了ByteBuffer的 directBuffer。 線程
對於讀寫網絡數據的buffer,分配策略有兩種:1)一般出於簡單考慮,直接分配固定大小的buffer,缺點是,對一些應用來講這個大小限制有 時是不 合理的,而且若是buffer的上限很大也會有內存上的浪費。2)針對固定大小的buffer缺點,就引入動態buffer,動態buffer之於固定 buffer至關於List之於Array。 code
buffer的寄存策略常見的也有兩種(實際上是我知道的就限於此):1)在多線程(線程池) 模型下,每一個線程維護本身的讀寫buffer,每次處理新的請求前清空buffer(或者在處理結束後清空),該請求的讀寫操做都須要在該線程中完成。 2)buffer和socket綁定而與線程無關。兩種方法的目的都是爲了重用buffer。 對象
Netty對buffer的處理策略是:讀 請求數據時,Netty首先讀數據到新建立的固定大小的HeapChannelBuffer中,當HeapChannelBuffer滿或者沒有數據可讀 時,調用handler來處理數據,這一般首先觸發的是用戶自定義的DecodeHandler,由於handler對象是和ChannelSocket 綁定的,因此在DecodeHandler裏能夠設置ChannelBuffer成員,當解析數據包發現數據不完整時就終止這次處理流程,等下次讀事件觸 發時接着上次的數據繼續解析。就這個過程來講,和ChannelSocket綁定的DecodeHandler中的Buffer一般是動態的可重用 Buffer(DynamicChannelBuffer),而在NioWorker中讀ChannelSocket中的數據的buffer是臨時分配的 固定大小的HeapChannelBuffer,這個轉換過程是有個字節拷貝行爲的。 接口
對ChannelBuffer的建立,Netty內部使用的是ChannelBufferFactory接口,具體的實現有 DirectChannelBufferFactory和HeapChannelBufferFactory。對於開發者建立 ChannelBuffer,可以使用實用類ChannelBuffers中的工廠方法。 事件