最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文學(xué)習(xí)Java NIO的ByteBuffer工作原理

 更新時(shí)間:2021年05月31日 14:19:59   作者:JavaEdge.  
很多網(wǎng)友說(shuō)JDK又在寫(xiě)B(tài)ug!下面通過(guò)通過(guò)本文學(xué)習(xí)下為何Java NIO的ByteBuffer這么垃圾,涉及到ByteBuf API 的優(yōu)點(diǎn)及工作原理解析,感興趣的朋友跟隨小編一起看看吧

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

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

1 API

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

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

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

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

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

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

2.1 工作原理

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

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


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

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

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

內(nèi)存池化

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

示意圖

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

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

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

示意圖

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

派生緩沖區(qū)

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

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

這些方法都將返回一個(gè)新的 ByteBuf 實(shí)例,但都具有自己獨(dú)立的讀、寫(xiě)和標(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)。

duplicate、retainedDuplicate

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

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

readSlice、readRetainedSlice

返回部分空間,彼此共享底層緩沖區(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ù)

通過(guò)在某個(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ì)象將被顯式釋放,并且訪問(wèn)釋放的對(duì)象通常會(huì)導(dǎo)致訪問(wèn)沖突。

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

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

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


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

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

一個(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é)釋放

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

以上就是一文學(xué)習(xí)Java NIO的ByteBuffer工作原理的詳細(xì)內(nèi)容,更多關(guān)于Java NIO的ByteBuffer的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 基于@LastModifiedDate不起作用的解決方案

    基于@LastModifiedDate不起作用的解決方案

    這篇文章主要介紹了基于@LastModifiedDate不起作用的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • 舉例說(shuō)明Java中代碼塊的執(zhí)行順序

    舉例說(shuō)明Java中代碼塊的執(zhí)行順序

    這篇文章主要介紹了舉例說(shuō)明Java中代碼塊的執(zhí)行順序,包括靜態(tài)屬性和非靜態(tài)屬性以及構(gòu)造函數(shù)等相關(guān)的執(zhí)行先后,需要的朋友可以參考下
    2015-07-07
  • Java多線程中的Interrupt簡(jiǎn)析

    Java多線程中的Interrupt簡(jiǎn)析

    這篇文章主要介紹了Java多線程中的Interrupt簡(jiǎn)析,Interrupt 的其作用是"中斷"線程, 但實(shí)際上線程仍會(huì)繼續(xù)運(yùn)行, 這是一個(gè)非常容易混淆的概念,Interrupt 的真正作用是給線程對(duì)象設(shè)置一個(gè)中斷標(biāo)記, 并不會(huì)影響線程的正常運(yùn)行,需要的朋友可以參考下
    2023-09-09
  • Java并發(fā)編程之關(guān)鍵字volatile的深入解析

    Java并發(fā)編程之關(guān)鍵字volatile的深入解析

    提高java的并發(fā)編程,就不得不提volatile關(guān)鍵字,不管是在面試還是實(shí)際開(kāi)發(fā)中volatile都是一個(gè)應(yīng)該掌握的技能,這篇文章主要給大家介紹了關(guān)于Java并發(fā)編程之關(guān)鍵字volatile的相關(guān)資料,需要的朋友可以參考下
    2021-09-09
  • Mybatis自定義typeHandle過(guò)程解析

    Mybatis自定義typeHandle過(guò)程解析

    這篇文章主要介紹了Mybatis自定義typeHandle過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Java調(diào)用IK分詞器進(jìn)行分詞方式,封裝工具類

    Java調(diào)用IK分詞器進(jìn)行分詞方式,封裝工具類

    這篇文章主要介紹了Java調(diào)用IK分詞器進(jìn)行分詞方式,封裝工具類,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Java OOM原因以及解決方案

    Java OOM原因以及解決方案

    這篇文章主要介紹了Java OOM原因以及解決方案,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • 淺析java貪心算法

    淺析java貪心算法

    這篇文章簡(jiǎn)單主要介紹了java貪心算法,包含貪心算法的基本思路,性質(zhì),以及實(shí)現(xiàn)示例,有需要的小伙伴參考下
    2015-02-02
  • java和matlab畫(huà)多邊形閉合折線圖示例講解

    java和matlab畫(huà)多邊形閉合折線圖示例講解

    由于要將“哈密頓回路問(wèn)題(TSP)”的求解中間結(jié)果表示出來(lái),查了一下使用程序畫(huà)多邊形圖形。現(xiàn)在在總結(jié)一下,這個(gè)圖是“由給定節(jié)點(diǎn)首尾相連的”閉合多邊形
    2014-02-02
  • Spring boot 配置多個(gè)redis的方法示例

    Spring boot 配置多個(gè)redis的方法示例

    這篇文章主要介紹了Spring boot 配置多個(gè)redis的方法示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09

最新評(píng)論

尤溪县| 洪湖市| 浦城县| 高唐县| 台前县| 安丘市| 桦川县| 迁安市| 阜康市| 龙州县| 内黄县| 曲沃县| 花莲县| 古蔺县| 东海县| 甘孜| 米易县| 商城县| 洪洞县| 白玉县| 靖宇县| 宝兴县| 东港市| 会同县| 手游| 平阴县| 黎城县| 花垣县| 元谋县| 武陟县| 沙坪坝区| 封开县| 屏边| 鄂托克前旗| 广元市| 天祝| 乌拉特中旗| 丘北县| 偏关县| 泰来县| 新野县|