亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java NIO的ByteBuffer工作原理是什么

發布時間:2021-05-31 16:03:52 來源:億速云 閱讀:289 作者:Leah 欄目:開發技術

這篇文章給大家介紹Java NIO的ByteBuffer工作原理是什么,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

1 API

Netty 的數據處理 API 通過兩個組件暴露——抽象類ByteBuf 和 接口 ByteBufHolder。

ByteBuf API 的優點:

  • 它可以被用戶自定義的緩沖區類型擴展

  • 通過內置的復合緩沖區類型實現了透明的零拷貝;

  • 容量可以按需增長(類似于 JDK 的 StringBuilder)

  • 在讀和寫這兩種模式之間切換不需要調用 ByteBuffer 的 flip()方法

  • 讀和寫使用了不同的索引

  • 支持方法的鏈式調用

  • 支持引用計數

  • 支持池化

其他類可用于管理 ByteBuf 實例的分配,以及執行各種針對于數據容器本身和它所持有的數據的操作。

2 Netty 的數據容器

所有網絡通信最終都是基于底層的字節流傳輸,因此高效、方便、易用的數據接口是迷人的,而 Netty 的 ByteBuf 生而為滿足這些需求。

2.1 工作原理

ByteBuf 維護倆不同索引:一個用于讀取,一個用于寫入:

  • 從 ByteBuf 讀取時,其 readerIndex 將會被遞增已經被讀取的字節數

  • 當寫入 ByteBuf 時,writerIndex 也會被遞增

  • 一個讀索引和寫索引都設置為 0 的 16 字節 ByteBuf

Java NIO的ByteBuffer工作原理是什么
Java NIO的ByteBuffer工作原理是什么

這些索引兩兩之間有什么關系呢?
若打算讀取字節直到 readerIndex == writerIndex,會發生啥?此時,將會到達“可讀取的”數據的末尾。類似試圖讀取超出數組末尾的數據一樣,試圖讀取超出該點的數據也會拋 IndexOutOfBoundsException

Java NIO的ByteBuffer工作原理是什么

  • read、write 開頭的 ByteBuf 方法,會推進對應索引

  • set、get 開頭的操作則不會。后面的這些方法將在作為一個參數傳入的一個相對索引上執行操作

可指定 ByteBuf 的最大容量。試圖移動寫索引(即 writerIndex)超過這個值將會觸
發一個異常。(默認限制 Integer.MAX_VALUE。)

內存池化

非池化的堆內與堆外的 ByteBuf

示意圖

Java NIO的ByteBuffer工作原理是什么

ByteBuf heapBuffer = UnpooledByteBufAllocator.DEFAULT.heapBuffer(10);
ByteBuf directBuffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(10);

注意要手動將GC 無法控制的非堆內存的空間釋放:

池化的堆內與堆外的 ByteBuf

示意圖

Java NIO的ByteBuffer工作原理是什么

Java NIO的ByteBuffer工作原理是什么

字節級操作

派生緩沖區

派生緩沖區為 ByteBuf 提供了以專門的方式來呈現其內容的視圖。這類視圖通過以下方法創建:

  • Unpooled.unmodifiableBuffer(…)

  • order(ByteOrder)

  • readSlice(int)

這些方法都將返回一個新的 ByteBuf 實例,但都具有自己獨立的讀、寫和標記索引。
其內部存儲和 JDK 的 ByteBuffer 一樣,都是共享的。所以派生緩沖區的創建成本很低,但同時也表明若你修改了它的內容,也會同時修改對應源實例!

slice、slice(int, int)、retainedSlice、retainedSlice(int, int)

返回此緩沖區的可讀字節的一部分
此方法與buf.slice(buf.readerIndex(), buf.readableBytes())相同。
該方法不會調用retain(),引用計數不會增加。
retainedSlice系列方法調用類似slice().retain(),但此方法可能返回產生較少垃圾的緩沖區實現。

Java NIO的ByteBuffer工作原理是什么

duplicate、retainedDuplicate

Java NIO的ByteBuffer工作原理是什么

返回一個共享該緩沖區整個區域的緩沖區。
此方法不會修改此緩沖區的readerIndex或writerIndex

Java NIO的ByteBuffer工作原理是什么

讀取器和寫入器標記將不會重復。
duplicate不會調用retain(),不會增加引用計數,而retainedDuplicate會。

readSlice、readRetainedSlice

Java NIO的ByteBuffer工作原理是什么

返回部分空間,彼此共享底層緩沖區,會增加原緩沖區的readerIndex。

如果需要一個現有緩沖區的真實副本,請使用 copy()或者 copy(int, int),因為這個調用所返回的 ByteBuf 擁有獨立的數據副本。

引用與釋放

ByteBuf 在使用完畢后一定要記得釋放,否則會造成內存泄露。

引用計數

通過在某個對象所持有的資源不再被其他對象引用時釋放該對象所持有的資源來優化內存使用和性能的技術。
Netty 在4.x為 ByteBuf 和 ByteBufHolder 帶來了引用計數技術,都實現了:

ReferenceCounted接口

需要顯式釋放的引用計數對象。

當一個新的ReferenceCounted被實例化時,以1 作為初始值。

retain()

增加引用計數,將引用計數加1。只要引用計數>0,就能保證對象不會被釋放。

release()

減少引用計數,將引用計數減1。若引用計數減少到0 ,對象將被顯式釋放,并且訪問釋放的對象通常會導致訪問沖突。

若實現ReferenceCounted的對象是其他實現ReferenceCounted的對象的容器,則當容器的引用計數變為 0 時,所包含的對象也將通過release()被釋放。

引用計數對于池化實現(如 PooledByteBufAllocator)很重要,它降低了內存分配的開銷。

Channel channel = ...;
// 從 Channel 獲取 ByteBufAllocator
ByteBufAllocator allocator = channel.alloc();
...
// 從 ByteBufAllocator 分配一個 ByteBuf
ByteBuf buffer = allocator.directBuffer();
// 檢查引用計數是否為預期的 1
assert buffer.refCnt() == 1;


ByteBuf buffer = ...;
// 減少該對象的活動引用。當減少到 0 時,該對象被釋放,該方法返回 true
boolean released = buffer.release();

試圖訪問一個已經被釋放的引用計數的對象,將會拋IllegalReferenceCountException

Java NIO的ByteBuffer工作原理是什么

Java NIO的ByteBuffer工作原理是什么

關于Java NIO的ByteBuffer工作原理是什么就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

黎平县| 应用必备| 攀枝花市| 米泉市| 岳阳县| 富锦市| 黑龙江省| 长汀县| 五莲县| 临颍县| 江孜县| 镇康县| 常山县| 和田市| 九龙城区| 齐齐哈尔市| 新竹县| 洮南市| 杨浦区| 罗江县| 马公市| 商洛市| 海丰县| 南涧| 阳信县| 舟山市| 茌平县| 江都市| 镇沅| 鄂尔多斯市| 轮台县| 遵义县| 夹江县| 青龙| 汝州市| 浮山县| 曲靖市| 泰安市| 金沙县| 江安县| 长春市|