国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

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

又又???UG啦!理智分析Java NIO的ByteBuffer到底有多難用

瀏覽:109日期:2022-08-11 11:18:17
目錄一、前言二、API三、Netty 的數(shù)據(jù)容器3.1 工作原理四、內(nèi)存池化五、字節(jié)級(jí)操作六、引用與釋放一、前言

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

二、API

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

ByteBuf API 的優(yōu)點(diǎn):

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

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

三、Netty 的數(shù)據(jù)容器

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

3.1 工作原理

ByteBuf 維護(hù)倆不同索引:一個(gè)用于讀取,一個(gè)用于寫入:

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

又又???UG啦!理智分析Java NIO的ByteBuffer到底有多難用又又???UG啦!理智分析Java NIO的ByteBuffer到底有多難用

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

又又???UG啦!理智分析Java NIO的ByteBuffer到底有多難用

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

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

四、內(nèi)存池化

非池化的堆內(nèi)與堆外的 ByteBuf 示意圖

又又???UG啦!理智分析Java NIO的ByteBuffer到底有多難用

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

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

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

又又???UG啦!理智分析Java NIO的ByteBuffer到底有多難用

又又???UG啦!理智分析Java NIO的ByteBuffer到底有多難用

五、字節(jié)級(jí)操作

派生緩沖區(qū)

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

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

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

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

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

又又???UG啦!理智分析Java NIO的ByteBuffer到底有多難用

duplicate、retainedDuplicate

又又???UG啦!理智分析Java NIO的ByteBuffer到底有多難用

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

又又???UG啦!理智分析Java NIO的ByteBuffer到底有多難用

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

readSlice、readRetainedSlice

又又???UG啦!理智分析Java NIO的ByteBuffer到底有多難用

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

如果需要一個(gè)現(xiàn)有緩沖區(qū)的真實(shí)副本,請(qǐng)使用 copy()或者 copy(int, int),因?yàn)檫@個(gè)調(diào)用所返回的 ByteBuf 擁有獨(dú)立的數(shù)據(jù)副本。

六、引用與釋放

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

引用計(jì)數(shù)

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

ReferenceCounted接口

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

當(dāng)一個(gè)新的ReferenceCounted被實(shí)例化時(shí),以1 作為初始值。

retain()

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

release()

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

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

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

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

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

又又???UG啦!理智分析Java NIO的ByteBuffer到底有多難用

又又???UG啦!理智分析Java NIO的ByteBuffer到底有多難用

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

誰(shuí)負(fù)責(zé)釋放

一般由最后訪問(引用計(jì)數(shù))對(duì)象的那一方來(lái)負(fù)責(zé)將它釋放。

到此這篇關(guān)于又又???UG啦!理智分析Java NIO的ByteBuffer到底有多難用的文章就介紹到這了,更多相關(guān)Java NIO的ByteBuffer內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 亚洲在线第一页 | 国产精品成人免费视频不卡 | 日韩精品在线一区二区 | 国产成人一区二区三区高清 | 国产原创一区二区 | 国产在线乱子伦一区二区 | 久久久久久青草大香综合精品 | 久久91精品国产91久久 | 美女黄页在线观看 | 色天天躁夜夜躁天干天干 | 女人夜色黄网在线观看 | 国产男女爽爽爽免费视频 | 舔操 | 99视频在线精品免费观看18 | 久久网站免费 | 最新国产精品亚洲 | 国产美女啪 | 精品亚洲福利一区二区 | 91探花福利精品国产自产在线 | 亚洲欧美日韩国产制服另类 | 国产成人亚洲日本精品 | 欧美日韩高清在线观看一区二区 | 宅男69免费永久网站 | 亚洲理论片在线中文字幕 | 美女白浆视频 | 114一级毛片免费观看 | 怡红院在线观看 | 欧美一级片在线视频 | 香港三级日本三级三级人妇 | 亚洲色视频在线播放网站 | 中文精品久久久久国产网址 | 亚洲国内精品自在线影视 | 欧美亚洲国产精品久久久 | 天堂素人搭讪系列嫩模在线观看 | 综合久久精品 | 日本成人午夜 | 国产一区二区三区欧美精品 | 成人a级 | 日本欧美韩国一区二区三区 | 大量愉拍情侣在线视频 | 久久久9视频在线观看 |