Netty ByteBuf入門

Netty ByteBuf

ByteBuf的基本結構

ByteBuf由一段地址空間碱呼,一個read index和一個write index組成。兩個index分別記錄讀寫進度燥滑,省去了NIO中ByteBuffer手動調(diào)用flip和clear的煩惱纺弊。

      +-------------------+------------------+------------------+
      | discardable bytes |  readable bytes  |  writable bytes  |
      |                   |     (CONTENT)    |                  |
      +-------------------+------------------+------------------+
      |                   |                  |                  |
      0      <=      readerIndex   <=   writerIndex    <=    capacity

通過上圖可以很好的理解ByteBuf的數(shù)據(jù)劃分筛璧。writer index到capacity之間的部分是空閑區(qū)域,可以寫入數(shù)據(jù)惹恃;reader index到writer index之間是已經(jīng)寫過還未讀取的可讀數(shù)據(jù)夭谤;0到reader index是已讀過可以釋放的區(qū)域。

三個index之間的關系是:reader index <= writer index <= capacity

存儲空間

ByteBuf根據(jù)其數(shù)據(jù)存儲空間不同有可以分為三種:基于JVM堆內(nèi)的巫糙,基于直接內(nèi)存的和組合的朗儒。

堆內(nèi)受JVM垃圾收集器的管轄,使用上相對安全一些参淹,不用每次手動釋放醉锄。弊端是GC是會影響性能的;還有就是內(nèi)存的拷貝帶來的性能損耗(JVM進程到Socket)浙值。

直接內(nèi)存則不受JVM的管轄恳不,省去了向JVM拷貝數(shù)據(jù)的麻煩。但是壞處就是別忘了釋放內(nèi)存开呐,否則就會發(fā)生內(nèi)存泄露烟勋。相比于堆內(nèi)存,直接內(nèi)存的的分配速度也比較慢筐付。

最佳實踐:在IO通信的線程中的讀寫B(tài)uffer使用DirectBuffer(省去內(nèi)存拷貝的成本)卵惦,在后端業(yè)務消息的處理使用HeapBuffer(不用擔心內(nèi)存泄露)。

通過hasArray檢查一個ByteBuf heap based還是direct buffer瓦戚。

創(chuàng)建ByteBuf

ByteBuf提供了兩個工具類來創(chuàng)建ByteBuf沮尿,分別是支持池化的Pooled和普通的Unpooled。Pooled緩存了ByteBuf的實例较解,提高性能并且減少內(nèi)存碎片蛹找。它使用Jemalloc來高效的分配內(nèi)存。

如果在Channel中我們可以通過channel.alloc()來拿到ByteBufAllocator哨坪,具體它使用Pool還是Unpool,Directed還是Heap取決于程序的配置乍楚。

索引的標記與恢復

markReaderIndex和resetReaderIndex是一個成對的操作当编。markReaderIndex可以打一個標記,調(diào)用resetReaderIndex可以把readerIndex重置到原來打標記的位置徒溪。

空間釋放

discardReadByte可以把讀過的空間釋放忿偷,這時buffer的readerIndex置為0,可寫空間和writerIndex也會相應的改變臊泌。discardReadBytes在內(nèi)存緊張的時候使用用鲤桥,但是調(diào)用該方法會伴隨buffer的內(nèi)存整理的。這是一個expensive的操作渠概。

clear是把readerIndex和writerIndex重置到0茶凳。但是嫂拴,它不會進行內(nèi)存整理,新寫入的內(nèi)容會覆蓋掉原有的內(nèi)容贮喧。

ByteBuf的派生與復制

派生操作會產(chǎn)生一個新的ByteBuf實例筒狠。這里的新指得是ByteBuf的引用是新的所有的index也是新的。但是它們共用著一套底層存儲箱沦。派生函數(shù):

  • duplicate()
  • slice()
  • slice(int, int)
  • readSlice(int)
  • retainedDuplicate()
  • retainedSlice()
  • retainedSlice(int, int)
  • readRetainedSlice(int)

如果想要復制一個全新的ByteBuffer請使用copy辩恼,這會完全的復制一個新的ByteBuf出來。

引用計數(shù)

引用計數(shù)記錄了當前ByteBuf被引用的次數(shù)谓形。新建一個ByteBuf它的refCnt是1灶伊,當refCnt == 0時,這個ByteBuf即可被回收寒跳。

引用技術主要用于內(nèi)存泄露的判斷聘萨,Netty提供了內(nèi)存泄露檢測工具。通過使用參數(shù)-Dio.netty.leakDetectionLevel=${level}可以配置檢測級別:

  • 禁用(DISABLED: 完全禁止泄露檢測冯袍,省點消耗匈挖。
  • 簡單(SIMPLE): 默認等級,告訴我們?nèi)拥?%的ByteBuf是否發(fā)生了泄露康愤,但總共一次只打印一次儡循,看不到就沒有了。
  • 高級(ADVANCED): 告訴我們?nèi)拥?%的ByteBuf發(fā)生泄露的地方征冷。每種類型的泄漏(創(chuàng)建的地方與訪問路徑一致)只打印一次择膝。對性能有影響。
  • 偏執(zhí)(PARANOID): 跟高級選項類似检激,但此選項檢測所有ByteBuf肴捉,而不僅僅是取樣的那1%。對性能有絕大的影響叔收。

查詢

很多時候需要從ByteBuf中查找特定的字符齿穗,比如LineBasedFrameDecoder需要在ByteBuf中查找'\r\n'。ByteBuf提供了簡單的indexOf這樣的函數(shù)饺律。同時也可以使用ByteProcesser來查找窃页。

以下gist提供了一些example。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末复濒,一起剝皮案震驚了整個濱河市脖卖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌巧颈,老刑警劉巖畦木,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異砸泛,居然都是意外死亡十籍,警方通過查閱死者的電腦和手機蛆封,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來妓雾,“玉大人娶吞,你說我怎么就攤上這事⌒狄觯” “怎么了妒蛇?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長楷拳。 經(jīng)常有香客問我绣夺,道長,這世上最難降的妖魔是什么欢揖? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任陶耍,我火速辦了婚禮,結果婚禮上她混,老公的妹妹穿的比我還像新娘烈钞。我一直安慰自己,他們只是感情好坤按,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布毯欣。 她就那樣靜靜地躺著,像睡著了一般臭脓。 火紅的嫁衣襯著肌膚如雪酗钞。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天来累,我揣著相機與錄音砚作,去河邊找鬼。 笑死嘹锁,一個胖子當著我的面吹牛葫录,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播领猾,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼压昼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了瘤运?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤匠题,失蹤者是張志新(化名)和其女友劉穎拯坟,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體韭山,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡郁季,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年冷溃,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片梦裂。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡似枕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出年柠,到底是詐尸還是另有隱情凿歼,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布冗恨,位于F島的核電站答憔,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏掀抹。R本人自食惡果不足惜虐拓,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望傲武。 院中可真熱鬧蓉驹,春花似錦、人聲如沸揪利。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽土童。三九已至诗茎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間献汗,已是汗流浹背敢订。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留罢吃,地道東北人楚午。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像尿招,于是被迫代替她去往敵國和親矾柜。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容