Netty源碼深度解析-ByteBuf(1) ByteBuf簡介

導(dǎo)讀

原創(chuàng)文章在跳,轉(zhuǎn)載請注明出處。

本文源碼地址:netty-source-code-analysis

本文所使用的netty版本4.1.6.Final:帶注釋的netty源碼

本文簡要地介紹ByteBuf的結(jié)構(gòu)鸣驱、主要api和創(chuàng)建方法哮内。

1 ByteBuf的結(jié)構(gòu)

每一個ByteBuf都有一個可容納的字節(jié)上限叫capacity圈暗。在ByteBuf中通過兩個指針readerIndexwriterIndex將整個個ByteBuf劃分成3個部分,分別是已丟棄部分缘挽、可讀部分可寫部分瞄崇,示意圖如下。

+-------------------+------------------+------------------+
|       已丟棄      |       可讀       |      可寫        |
|                   |     (CONTENT)    |                  |
+-------------------+------------------+------------------+
|                   |                  |                  |
0      <=      readerIndex   <=   writerIndex    <=    capacity

readerIndex壕曼、writerIndexcapacity之間滿足簡單地數(shù)學(xué)關(guān)系0 <= readerIndex <= writerIndex <= capcity苏研。

一個新建的從未進(jìn)行過讀寫操作的ByteBufreaderIndexwriterIndex都為0腮郊。整個空間都是可寫部分摹蘑。

+---------------------------------------------------------+
|                           可寫                          |
|                                                         |
+---------------------------------------------------------+
|                                                         |
0                                                      capacity
readerIndex
writerIndex

現(xiàn)在往其中寫入一些數(shù)據(jù),寫數(shù)據(jù)的過程會引起writerIndex的移動轧飞,writerIndex移動的最大值為capacity衅鹿,寫數(shù)據(jù)的過程中readerIndex保持不變。

+--------------------------------------+------------------+
|                  可讀                |      可寫        |
|               (CONTENT)              |                  |
+--------------------------------------+------------------+
|                                      |                  |
0                   <=            writerIndex    <=    capacity
readerIndex

接著讀取一些數(shù)據(jù)过咬,讀數(shù)據(jù)的過程會引起readerIndex的移動大渤,readerIndex的最大值為writerIndex,在讀數(shù)據(jù)的過程中writerIndex保持不變掸绞。已經(jīng)被讀取過的部分就成了已丟棄部分泵三。

+-------------------+------------------+------------------+
|       已丟棄      |       可讀       |      可寫        |
|                   |     (CONTENT)    |                  |
+-------------------+------------------+------------------+
|                   |                  |                  |
0      <=      readerIndex   <=   writerIndex    <=    capacity

2 ByteBuf的主要方法

2.1 write族方法

write族方法用來向ByteBuf中寫入各種類型的數(shù)據(jù),比如writeByteswriteChar烫幕、writeInt等俺抽。另外支持寫入小端字節(jié)序數(shù)據(jù),比如writeIntLE较曼、writeLongLE等凌埂。

write族方法的調(diào)用時寫入數(shù)據(jù)的起始位置就是當(dāng)前writerIndex指向的位置,寫入數(shù)據(jù)會引起writerIndex的移動诗芜。

2.2 read族方法

read族方法用來從ByteBuf中讀取數(shù)據(jù),比如readBytes埃疫、writeBytes伏恐、writeLong等。同樣也支持讀取小端字節(jié)序數(shù)據(jù)栓霜,比如readIntLE翠桦、readLongLE等。

read族方法的調(diào)用會引起readerIndex的移動胳蛮。

2.3 set族方法

write族方法一樣销凑,set族方法同樣用來向ByteBuf中寫入各種類型的數(shù)據(jù)。write能寫入的數(shù)據(jù)set也能仅炊,比如writeIntsetInt斗幼。不同的是set族方法在調(diào)用時需要傳遞一個索引參數(shù),也就是說需要指定寫入數(shù)據(jù)的位置抚垄,比如writeInt(int value)setInt(int index, int value)蜕窿。

set族方法的調(diào)用不會引起writerIndex的移動。

2.4 get族方法

read族方法一樣呆馁,get族方法同樣用來從ByteBuf中讀取數(shù)據(jù)桐经。比如有getIntgetLong方法浙滤。與read族方法不一樣的是在調(diào)用時需要傳遞一個索引參數(shù)阴挣,也就是說需要指定讀取數(shù)據(jù)的位置,比如getInt(int index)readInt()纺腊。

read族方法的調(diào)用不會引起readerIndex的移動畔咧。

2.5 讀取/設(shè)置 Index的方法

ByteBuf提供了writerIndex()readerIndex()方法分別可以返回當(dāng)前的writerIndexreaderIndex

除了readwrite方法可以改變readerIndexwriterIndex摹菠,ByteBuf也提供了可以手動設(shè)置readerIndexreaderIndex(int readerIndex)及手動設(shè)置writerIndexwriterIndex(int writerIndex)方法盒卸。

2.6 slice方法

slice方法將當(dāng)前ByteBuf的可讀數(shù)據(jù)區(qū)映射到一個新的ByteBuf,并返回這個新的ByteBuf次氨。這個新的ByteBuf與原ByteBuf共享數(shù)據(jù)區(qū)域蔽介,但是擁有獨(dú)立的readerIndexwriterIndex

也提供了slice(int index, int length)方法可以指定映射的數(shù)據(jù)區(qū)域范圍。

對新的ByteBuf數(shù)據(jù)的修改同樣會影響到的原來的ByteBuf的數(shù)據(jù)虹蓄,反之亦然犀呼。

2.7 duplicate方法

duplicate方法將當(dāng)前ByteBuf的整個數(shù)據(jù)區(qū)映射到一個新的ByteBuf,并返回這個新的ByteBuf薇组。這個新的ByteBuf與原ByteBuf共享數(shù)據(jù)區(qū)域外臂,但是擁有獨(dú)立的readerIndexwriterIndex

對新的ByteBuf數(shù)據(jù)的修改同樣會影響到的原來的ByteBuf的數(shù)據(jù)律胀,反之亦然宋光。

2.8 copy方法

copy方法返回當(dāng)前ByteBuf的一個復(fù)制品,新的ByteBuf擁有與原來的ByteBuf不一樣的數(shù)據(jù)區(qū)域炭菌,readerIndexwriterIndex也是獨(dú)立的罪佳。

同樣提供了copy(int index, int length)方法可以指定復(fù)制的數(shù)據(jù)區(qū)域范圍。

對新的ByteBuf數(shù)據(jù)的修改不會影響到原來的ByteBuf黑低,反之亦然赘艳。

2.9 retain和release方法

ByteBuf使用引用計數(shù)法來表示當(dāng)前ByteBuf被引用的次數(shù),如果一個ByteBuf的被引用次數(shù)為0克握,則釋放該ByteBuf對應(yīng)的內(nèi)存蕾管。

3 ByteBuf的主要實現(xiàn)及創(chuàng)建

ByteBuf的主要實現(xiàn)類圖如下圖所示,總體上分為PooledUnPooled兩類菩暗,顧名思義為池化的和非池化的掰曾,又根據(jù)分配的是直接內(nèi)存還是堆內(nèi)存分為HeapByteBufDirectByteBuf

ByteBuf類圖

3.1 通過ByteBufAllocator創(chuàng)建

ByteBufAllocator有兩個實現(xiàn)分別為PooledByteBufAllocatorUnpooledByteBufAllocator對應(yīng)分配出來是的PooledByteBufUnpooledByteBuf停团。
PooledByteBufAllocator將在后續(xù)的文章中重點(diǎn)分析婴梧,而UnpooledByteBufAllocator則比較簡單,不再贅述客蹋。

3.2 通過包裹ByteBuffer及byte[]創(chuàng)建

使用Unpooled.wrappedBuffer方法可以對jdkButeBufferbyte[]進(jìn)行包裹創(chuàng)建出一個UnpooledByteBuf塞蹭。

4 總結(jié)

ByteBuf主要api有read/write,get/set讶坯,slice番电,duplicate,copy等系列方法辆琅。實現(xiàn)類上主要分為UnpooledPooled漱办,并且支持分配HeapByteBufDirectByteBuf


關(guān)于作者

王建新婉烟,轉(zhuǎn)轉(zhuǎn)架構(gòu)部服務(wù)治理負(fù)責(zé)人娩井,主要負(fù)責(zé)服務(wù)治理、RPC框架似袁、分布式調(diào)用跟蹤洞辣、監(jiān)控系統(tǒng)等咐刨。愛技術(shù)、愛學(xué)習(xí)扬霜,歡迎聯(lián)系交流定鸟。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市著瓶,隨后出現(xiàn)的幾起案子联予,更是在濱河造成了極大的恐慌,老刑警劉巖材原,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沸久,死亡現(xiàn)場離奇詭異,居然都是意外死亡余蟹,警方通過查閱死者的電腦和手機(jī)麦向,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來客叉,“玉大人,你說我怎么就攤上這事话告〖娌” “怎么了?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵沙郭,是天一觀的道長佛呻。 經(jīng)常有香客問我,道長病线,這世上最難降的妖魔是什么吓著? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮送挑,結(jié)果婚禮上绑莺,老公的妹妹穿的比我還像新娘。我一直安慰自己惕耕,他們只是感情好纺裁,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著司澎,像睡著了一般欺缘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上挤安,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天谚殊,我揣著相機(jī)與錄音,去河邊找鬼蛤铜。 笑死嫩絮,一個胖子當(dāng)著我的面吹牛丛肢,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播絮记,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼摔踱,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了怨愤?” 一聲冷哼從身側(cè)響起派敷,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎撰洗,沒想到半個月后篮愉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡差导,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年试躏,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片设褐。...
    茶點(diǎn)故事閱讀 40,110評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡颠蕴,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出助析,到底是詐尸還是另有隱情犀被,我是刑警寧澤,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布外冀,位于F島的核電站寡键,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏雪隧。R本人自食惡果不足惜西轩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望脑沿。 院中可真熱鬧藕畔,春花似錦、人聲如沸庄拇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽丛忆。三九已至祠汇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間熄诡,已是汗流浹背可很。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留凰浮,地道東北人我抠。 一個月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓苇本,卻偏偏與公主長得像,于是被迫代替她去往敵國和親菜拓。 傳聞我的和親對象是個殘疾皇子瓣窄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評論 2 355

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