日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Netty 4.x – ByteBuf

發布時間:2023/12/6 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Netty 4.x – ByteBuf 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

1、ByteBuf與Java NIO Buffer

ByteBuf則是Java NIO Buffer的新輪子,官方列出了一些ByteBuf的特性:

  • 需要的話,可以自定義buffer類型;
  • 通過組合buffer類型,可實現透明的zero-copy;
  • 提供動態的buffer類型,如StringBuffer一樣,容量是按需擴展;
  • 無需調用flip()方法;
  • 常常「often」比ByteBuffer快。

?

2、ByteBuf實現類

ByteBuf提供了一些較為豐富的實現類,邏輯上主要分為兩種:HeapByteBuf和DirectByteBuf,實現機制則分為兩種:PooledByteBuf和UnpooledByteBuf,除了這些之外,Netty還實現了一些衍生ByteBuf(DerivedByteBuf),如:ReadOnlyByteBuf、DuplicatedByteBuf以及SlicedByteBuf。

ByteBuf實現類的類圖如下:

HeapByteBuf和DirectByteBuf區別在于Buffer的管理方式:HeapByteBuf由Heap管理,Heap是Java堆的意思,內部實現直接采用byte[] array;DirectByteBuf使用是堆外內存,Direct應是采用Direct I/O之意,內部實現使用java.nio.DirectByteBuffoer。

PooledByteBuf和UnpooledByteBuf,UnpooledByteBuf實現就是普通的ByteBuf了,PooledByteBuf是4.x之后的新特性,稍后再說。

DerivedByteBuf是ByteBuf衍生類,實現采用裝飾器模式對原有的ByteBuf進行了一些封裝。ReadOnlyByteBuf是某個ByteBuf的只讀引用;DuplicatedByteBuf是某個ByteBuf對象的引用;SlicedByteBuf是某個ByteBuf的部分內容。

SwappedByteBuf和CompositedByteBuf我覺得也算某種程度的衍生類吧,SwappedByteBuf封裝了一個ByteBuf對象和ByteOrder對象,實現某個ByteBuf對象序列的逆轉;CompositedByteBuf內部實現了一個ByteBuf列表,稱之為組合ByteBuf,由于不懂相關的技術業務,無法理解該類的存在意義(官方解釋:A user can save bulk memory copy operations using a composite buffer at the cost of relatively expensive random access.)。這兩個類從邏輯上似乎完全可以繼承于DerivedByteBuf,Trustin大神為啥如此設計呢?

3、簡要的ByteBuf的實現機制

ByteBuf有兩個指針,readerIndex和writerIndex,用以控制buffer數組的讀寫。讀邏輯較為簡單,不考慮邊界的情況下,就是`return array[readerIndex++];`。這里簡要分析一下HeapByteBuf的讀邏輯。

1. AbstractByteBuf.ensureWritable(minWritableBytes);

2. calculateNewCapacity(writerIndex + minWritableBytes)

> 2.1 判斷是否超過可寫入容量 maxCapacity – writerIndex

> 2.2 超過則拋異常,否則計算新容量 writerIndex + minWritableBytes

> 2.3 判斷是否超過設定閾值(4MB),超過每次增加按閾值(4MB)遞增,否則

> 2.4 初始大小為64字節(newCapacity),新容量超過newCapacity則翻倍,直到newCapacity大于新容量為止

> 2.5 返回Min(newCapacity, maxCapacity);

3. UnpooledHeapByteBuf.capacity(newCapacity);

> 3.1 確保可訪問,有一個`引用計數`的機制,引用計數為0,則拋異常(ensureAccessible)

> 3.2 常規操作:判斷是否越界

> 3.3 如果newCapacity比原容量大,則直接創建新數組,并設置。否則

> 3.4 如果readerIndex小于新容量,將readable bytes拷貝至新的數組,反之將readerIndex和writerIndex均設置為newCapacity。

4. setByte(writerIndex++, value)

> 4.1 確保可訪問

> 4.2 設置

5、ByteBuf特殊機制

5.1 Pooled

4.x開發了Pooled Buffer,實現了一個高性能的buffer池,分配策略則是結合了buddy allocation和slab allocation的jemalloc變種,代碼在io.netty.buffer.PoolArena。暫未深入研讀。

官方說提供了以下優勢:

  • 頻繁分配、釋放buffer時減少了GC壓力;
  • 在初始化新buffer時減少內存帶寬消耗(初始化時不可避免的要給buffer數組賦初始值);
  • 及時的釋放direct buffer。

當然,官方也說了不保證沒有內存泄露,所以默認情況下還是采用的UnpooledByteBufAllocator。5.x還處于beta版,看它的「?new and noteworthy?」文檔也沒說有啥變化,哈哈哈哈,查看最新的「?new and noteworthy?」文檔,PooledByteBufAllocator已經設置為默認的Allocator (revised in 2014-01-16)。

5.2 Reference Count

ByteBuf的生命周期管理引入了Reference Count的機制,感覺讓我回到了CPP時代。可以通過簡單的繼承SimpleChannelInboundHandler實現自動釋放reference count。SimpleChannelInboundHandler的事件方法如下,在消費完畢msg后,可以AutoRelease之:

public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {boolean release = true;try {if (acceptInboundMessage(msg)) {@SuppressWarnings("unchecked")I imsg = (I) msg;messageReceived(ctx, imsg);} else {release = false;ctx.fireChannelRead(msg);}} finally {if (autoRelease && release) {ReferenceCountUtil.release(msg);}}}

這一小節可以單獨拎出來和Pooled放在一起深入研讀研讀,有興趣的可以先看看官方文檔:?Reference counted objects

5.3 Zero Copy

Zero-copy與傳統意義的?zero-copy?不太一樣。傳統的zero-copy是IO傳輸過程中,數據無需中內核態到用戶態、用戶態到內核態的數據拷貝,減少拷貝次數。而Netty的zero-copy則是完全在用戶態,或者說傳輸層的zero-copy機制,可以參考下圖。由于協議傳輸過程中,通常會有拆包、合并包的過程,一般的做法就是System.arrayCopy了,但是Netty通過ByteBuf.slice以及Unpooled.wrappedBuffer等方法拆分、合并Buffer無需拷貝數據。

如何實現zero-copy的呢。slice實現就是創建一個SlicedByteBuf對象,將this對象,以及相應的數據指針傳入即可,wrappedBuffer實現機制類似。

?

?

?

?

?

轉載于:https://my.oschina.net/LucasZhu/blog/1799162

總結

以上是生活随笔為你收集整理的Netty 4.x – ByteBuf的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。