亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術(shù)文章
文章詳情頁

一文學習Java NIO的ByteBuffer工作原理

瀏覽:2日期:2022-08-11 15:12:28
目錄1 API2 Netty 的數(shù)據(jù)容器2.1 工作原理內(nèi)存池化非池化的堆內(nèi)與堆外的 ByteBuf池化的堆內(nèi)與堆外的 ByteBuf字節(jié)級操作派生緩沖區(qū)slice、slice(int, int)、retainedSlice、retainedSlice(int, int)duplicate、retainedDuplicatereadSlice、readRetainedSlice

網(wǎng)絡(luò)數(shù)據(jù)的基本單位永遠是 byte(字節(jié))。Java NIO 提供 ByteBuffer 作為字節(jié)的容器,但該類過于復雜,有點難用。

ByteBuf是Netty當中的最重要的工具類,它與JDK的ByteBuffer原理基本上相同,也分為堆內(nèi)與堆外倆種類型,但是ByteBuf做了極大的優(yōu)化,具有更簡單的API,更多的工具方法和優(yōu)秀的內(nèi)存池設(shè)計。

1 API

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

ByteBuf API 的優(yōu)點:

它可以被用戶自定義的緩沖區(qū)類型擴展 通過內(nèi)置的復合緩沖區(qū)類型實現(xiàn)了透明的零拷貝; 容量可以按需增長(類似于 JDK 的 StringBuilder) 在讀和寫這兩種模式之間切換不需要調(diào)用 ByteBuffer 的 flip()方法 讀和寫使用了不同的索引 支持方法的鏈式調(diào)用 支持引用計數(shù) 支持池化

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

2 Netty 的數(shù)據(jù)容器

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

2.1 工作原理

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

從 ByteBuf 讀取時,其 readerIndex 將會被遞增已經(jīng)被讀取的字節(jié)數(shù) 當寫入 ByteBuf 時,writerIndex 也會被遞增 一個讀索引和寫索引都設(shè)置為 0 的 16 字節(jié) ByteBuf

一文學習Java NIO的ByteBuffer工作原理一文學習Java NIO的ByteBuffer工作原理

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

一文學習Java NIO的ByteBuffer工作原理

read、write 開頭的 ByteBuf 方法,會推進對應(yīng)索引 set、get 開頭的操作則不會。后面的這些方法將在作為一個參數(shù)傳入的一個相對索引上執(zhí)行操作

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

內(nèi)存池化非池化的堆內(nèi)與堆外的 ByteBuf

示意圖

一文學習Java NIO的ByteBuffer工作原理

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

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

池化的堆內(nèi)與堆外的 ByteBuf

示意圖

一文學習Java NIO的ByteBuffer工作原理

一文學習Java NIO的ByteBuffer工作原理

字節(jié)級操作派生緩沖區(qū)

派生緩沖區(qū)為 ByteBuf 提供了以專門的方式來呈現(xiàn)其內(nèi)容的視圖。這類視圖通過以下方法創(chuàng)建:

Unpooled.unmodifiableBuffer(…) order(ByteOrder) readSlice(int)

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

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

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

一文學習Java NIO的ByteBuffer工作原理

duplicate、retainedDuplicate

一文學習Java NIO的ByteBuffer工作原理

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

一文學習Java NIO的ByteBuffer工作原理

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

readSlice、readRetainedSlice

一文學習Java NIO的ByteBuffer工作原理

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

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

引用與釋放

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

引用計數(shù)

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

ReferenceCounted接口

需要顯式釋放的引用計數(shù)對象。

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

retain()

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

release()

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

若實現(xiàn)ReferenceCounted的對象是其他實現(xiàn)ReferenceCounted的對象的容器,則當容器的引用計數(shù)變?yōu)?0 時,所包含的對象也將通過release()被釋放。

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

Channel channel = ...;// 從 Channel 獲取 ByteBufAllocatorByteBufAllocator allocator = channel.alloc();...// 從 ByteBufAllocator 分配一個 ByteBufByteBuf buffer = allocator.directBuffer();// 檢查引用計數(shù)是否為預期的 1assert buffer.refCnt() == 1;ByteBuf buffer = ...;// 減少該對象的活動引用。當減少到 0 時,該對象被釋放,該方法返回 trueboolean released = buffer.release();

試圖訪問一個已經(jīng)被釋放的引用計數(shù)的對象,將會拋IllegalReferenceCountException

一文學習Java NIO的ByteBuffer工作原理

一文學習Java NIO的ByteBuffer工作原理

一個特定的(ReferenceCounted 的實現(xiàn))類,可以用它自己的獨特方式來定義它的引用計數(shù)規(guī)則。例如可以設(shè)想一個類,其 release()方法的實現(xiàn)總是將引用計數(shù)設(shè)為零,而不用關(guān)心它的當前值,從而一次性使所有的活動引用都失效。

誰負責釋放

一般由最后訪問(引用計數(shù))對象的那一方來負責將它釋放。

以上就是一文學習Java NIO的ByteBuffer工作原理的詳細內(nèi)容,更多關(guān)于Java NIO的ByteBuffer的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標簽: Java
相關(guān)文章:
主站蜘蛛池模板: 欧美亚洲视频在线观看 | 成人在线一区二区 | 免费人成黄页在线观看视频国产 | 一级毛片视频免费 | 日本免费二区三区久久 | 狠狠色依依成人婷婷九月 | 黄色小视频在线免费观看 | 婷婷六月久久综合丁香乐透 | 久久草精品视频 | 91精品国产9l久久久久 | 国产成人在线网站 | 四库影库免费永久在线 | 日本一级特黄毛片免费视频 | 一级黄色免费看 | 国产精品久久久影院 | 婷婷丁香在线视频 | 国产精品香蕉在线一区 | 在线亚洲一区 | 婷婷在线网 | 国产精品久久做爰 | 日韩欧美中文字幕出 | 日本不卡高清免费v | 亚洲九九夜夜 | 欧美啪啪网址 | 在线观看毛片视频 | 啪啪网址免费网址 | 亚洲国产精品专区 | 国产高颜值露脸在线观看 | 亚洲精品国产精品国自产网站 | 亚洲成人免费网址 | 欧美大吊视频 | 亚洲欧美另类一区 | 黄色三及片 | xvideos亚洲永久网址 | 国产一级免费视频 | 123456成年免费视频 | 水蜜桃爱爱yy视频在线观看 | 黄色在线| 亚洲精品亚洲人成人网 | 国产精品免费久久久免费 | 自偷自偷自亚洲永久 |