摘要:主要用來(lái)檢測(cè)對(duì)象是否泄漏。子類(lèi)實(shí)現(xiàn)相關(guān)的方法是否支持?jǐn)?shù)組,判斷緩沖區(qū)的實(shí)現(xiàn)是否基于字節(jié)數(shù)組如果緩沖區(qū)的實(shí)現(xiàn)基于字節(jié)數(shù)組,返回字節(jié)數(shù)組
ByteBuf
ByteBuf需要提供JDK ByteBuffer的功能(包含且不限于),主要有以下幾類(lèi)基本功能:
7種Java基礎(chǔ)類(lèi)型、byte[]、ByteBuffer(ByteBuf)的等的讀寫(xiě)
緩沖區(qū)自身的copy和slice
設(shè)置網(wǎng)絡(luò)字節(jié)序
構(gòu)造緩沖區(qū)實(shí)例
操作位置指針
擴(kuò)容原理首先確認(rèn)ByteBuf是否已經(jīng)被釋放,如果被釋放,則拋出IllegalReferenceCountException異常
判斷寫(xiě)入需要的最小空間,如果該空間小于ByteBuf的可寫(xiě)入空間,直接返回,不進(jìn)行擴(kuò)容
判斷寫(xiě)入需要的最小空間,如果該空間大于ByteBuf的(最大容量-當(dāng)前的寫(xiě)索引),不進(jìn)行擴(kuò)容,拋出IndexOutOfBoundsException異常
計(jì)算新容量,動(dòng)態(tài)擴(kuò)容的規(guī)則,當(dāng)新容量大于4MB時(shí),以4MB的方式遞增擴(kuò)容,在小于4MB時(shí),從64字節(jié)開(kāi)始倍增(Double)擴(kuò)容
讀寫(xiě)索引Netty提供readIndex和writeIndex用來(lái)支持讀取和寫(xiě)入操作,兩個(gè)索引將緩沖區(qū)劃分為三個(gè)區(qū)域
0 ~ readIndex:已讀區(qū)域(可丟棄區(qū)域)
readIndex ~ writeIndex:未讀取區(qū)域
writeIndex ~ capacity:待寫(xiě)入?yún)^(qū)域
已讀區(qū)域(Discardable Bytes)位于已讀區(qū)域的內(nèi)容表明該內(nèi)容已被Netty處理完成,我們可以重用這塊緩沖區(qū),盡量減少緩沖區(qū)的動(dòng)態(tài)擴(kuò)容(復(fù)制,耗時(shí)操作)。
調(diào)用discardBytes()方法可以清除已讀區(qū)域內(nèi)容,但同時(shí)會(huì)導(dǎo)致未讀區(qū)域的左移,也是將未讀區(qū)域的內(nèi)容復(fù)制到原來(lái)的已讀區(qū)域(耗時(shí)),
因此頻繁的調(diào)用discardBytes也是不可取的,可以根據(jù)實(shí)際情況進(jìn)行調(diào)用。
Readable Bytes(可讀空間)存儲(chǔ)的是未被讀取處理的內(nèi)容,以read或者skip開(kāi)頭的方法都會(huì)從readIndex開(kāi)始讀取或者跳過(guò)指定的數(shù)據(jù),同時(shí)readIndex會(huì)增加讀取或跳過(guò)
的字節(jié)數(shù)長(zhǎng)度。如果讀取的字節(jié)數(shù)長(zhǎng)度大于實(shí)際可讀取的字節(jié)數(shù),拋出IndexOutOfBoundsException異常。
Writable Bytes(可寫(xiě)入空間)是未被數(shù)據(jù)填充的緩沖區(qū)塊,以write開(kāi)頭的操作都會(huì)從writeIndex開(kāi)始向緩沖區(qū)寫(xiě)入數(shù)據(jù),同時(shí)writeIndex會(huì)增加寫(xiě)入的數(shù)據(jù)的字節(jié)數(shù)長(zhǎng)度。
如果寫(xiě)入的字節(jié)數(shù)大于可寫(xiě)入的字節(jié)數(shù),會(huì)拋出IndexOutOfBoundsException異常。
Clear操作并不會(huì)清除緩沖區(qū)的內(nèi)容,只是將readIndex和writeIndex還原為初始分配值。
Mark和ResetmarkReadIndex
resetReadIndex
markWriteIndex
resetWriteIndex
查找操作indexOf(int fromIndex, int toIndex, byte value):fromIndex<=toIndex時(shí),從頭開(kāi)始查找首次出現(xiàn)value的位置(查找范圍fromIndex ~ toIndex),當(dāng)fromIndex > toIndex時(shí),倒著查找首次出現(xiàn)value的位置(查找的范圍toIndex ~ fromIndex - 1),查不到返回-1
bytesBefore(byte value):從ByteBuf的可讀區(qū)域中首次定位出現(xiàn)value的位置,沒(méi)有找到返回-1。該方法不會(huì)修改readIndex和writeIndex
bytesBefore(int length, byte value):從ByteBuf的可讀區(qū)域中定位首次出現(xiàn)value的位置,結(jié)束索引是readIndex+length。如果length大于可讀字節(jié)數(shù),拋出IndexOutOfBoundsException異常
bytesBefore(int index, int length, byte value):從ByteBuf中定位首次出現(xiàn)value的位置,起始索引為index,結(jié)束索引為index+length,如果index+length大于當(dāng)前緩沖區(qū)的容量,拋出IndexOutOfBoundsException異常
forEachByte(int index, int length, ByteProcessor processor):從index開(kāi)始,到index + length結(jié)束,與ByteProcessor設(shè)置的查找條件進(jìn)行對(duì)比,滿(mǎn)足條件,返回位置索引,否則返回-1
forEachByteDesc(ByteProcessor processor):倒序遍歷ByteBuf的可讀字節(jié)數(shù)組,與ByteProcessor設(shè)置的查找條件進(jìn)行對(duì)比,滿(mǎn)足條件,返回位置索引,否則返回-1
forEachByteDesc(int index, int length, ByteProcessor processor):以index + length - 1開(kāi)始,直到index結(jié)束,倒序遍歷ByteBuf字節(jié)數(shù)組,與ByteProcessor設(shè)置的查找條件進(jìn)行對(duì)比,滿(mǎn)足條件,返回位置索引,否則返回-1
Netty提供了大量的默認(rèn)的ByteProcessor,來(lái)對(duì)常用的查找自己進(jìn)行查找,具體可見(jiàn)ByteProcessor接口。
Derived buffers(派生緩沖區(qū))duplicate():返回當(dāng)前ByteBuf的復(fù)制對(duì)象,復(fù)制后返回的ByteBuf與操作的ByteBuf共享緩沖區(qū)內(nèi)容,但是維護(hù)自己獨(dú)立的讀寫(xiě)索引。當(dāng)修改復(fù)制后的ByteBuf內(nèi)容后,原ByteBuf的內(nèi)容也隨之改變,因?yàn)殡p方持有的是同一個(gè)內(nèi)容的指針引用。
copy():復(fù)制一個(gè)新的ByteBuf對(duì)象,內(nèi)容和索引都與原ByteBuf獨(dú)立,復(fù)制操作本身并不修改原ByteBuf的讀寫(xiě)索引
copy(int index, int length):復(fù)制一個(gè)新的ByteBuf對(duì)象,復(fù)制開(kāi)始的索引為index,復(fù)制的長(zhǎng)度為length
slice():返回與當(dāng)前ByteBuf的可讀子緩沖區(qū),范圍是readIndex ~ writeIndex,返回后的ByteBuf與原ByteBuf內(nèi)容共享,讀寫(xiě)索引獨(dú)立維護(hù),maxCapacity是當(dāng)前ByteBuf的可讀字節(jié)數(shù)(換句話(huà)說(shuō)就是這個(gè)新返回的緩沖區(qū)不能再進(jìn)行寫(xiě)入)
slice(int index, int length):返回index開(kāi)始,length長(zhǎng)度的當(dāng)前ByteBuf的子緩沖區(qū),返回后的ByteBuf與原ByteBuf內(nèi)容共享,讀寫(xiě)索引獨(dú)立維護(hù),maxCapacity是length(換句話(huà)說(shuō)就是這個(gè)新返回的緩沖區(qū)不能再進(jìn)行寫(xiě)入)
轉(zhuǎn)換成標(biāo)準(zhǔn)的ByteBufferByteBuffer nioBuffer():將當(dāng)前ByteBuf可讀的緩沖區(qū)轉(zhuǎn)換成ByteBuffer,兩者共享同一個(gè)緩沖區(qū)內(nèi)容引用,對(duì)ByteBuffer的讀寫(xiě)操作并不會(huì)修改原ByteBuf的讀寫(xiě)索引。返回后的ByteBuffer無(wú)法感知ByteBuf的動(dòng)態(tài)擴(kuò)展。
ByteBuffer nioBuffer(int index, int length):從ByteBuf的index位置開(kāi)始長(zhǎng)度為length的緩沖區(qū)轉(zhuǎn)換成ByteBuffer,兩者共享同一個(gè)緩沖區(qū)內(nèi)容引用,對(duì)ByteBuffer的讀寫(xiě)操作并不會(huì)修改原ByteBuf的讀寫(xiě)索引。返回后的ByteBuffer無(wú)法感知ByteBuf的動(dòng)態(tài)擴(kuò)展。
隨機(jī)讀寫(xiě)主要通過(guò)set和get開(kāi)頭的方法,這兩個(gè)方法可以指定索引位置。
ByteBuf源碼從內(nèi)存分配的角度來(lái)看,ByteBuf主要分為以下兩類(lèi):
堆內(nèi)存(HeapByteBuf)字節(jié)緩沖區(qū):內(nèi)存分配和回收速度快,可以被JVM自動(dòng)回收;缺點(diǎn)是如果Socket進(jìn)行I/O讀寫(xiě),需要進(jìn)行一次內(nèi)存復(fù)制,將堆內(nèi)存對(duì)應(yīng)的緩沖區(qū)復(fù)制到內(nèi)核Channel中,性能會(huì)有所下降
直接內(nèi)存(DirectByteBuf)字節(jié)緩沖區(qū):堆外內(nèi)存直接分配,相比于堆內(nèi)存,分配和回收速度比較慢,但是在Socket Channel中進(jìn)行讀寫(xiě)比較快(少一次內(nèi)存復(fù)制)
ByteBuf的最佳時(shí)間是在I/O通信線(xiàn)程的讀寫(xiě)緩沖區(qū)使用DirectByteBuf,后端業(yè)務(wù)消息的編解碼模塊使用HeapByteBuf。
從內(nèi)存回收的角度進(jìn)行分類(lèi):
基于對(duì)象池的ByteBuf:自己維護(hù)了一個(gè)內(nèi)存池,可以重復(fù)利用ByteBuf對(duì)象,提升內(nèi)存使用率,降低GC頻率
普通的ByteBuf
AbstractByteBufAbstractByteBuf繼承ByteBuf,ByteBuf中的一些公共屬性和方法會(huì)在AbstractByteBuf中實(shí)現(xiàn)。
主要變量ResourceLeakDetector
索引設(shè)置:讀寫(xiě)索引、重置讀寫(xiě)索引、最大容量
讀操作讀操作的公共功能由父類(lèi)實(shí)現(xiàn),差異化由具體的子類(lèi)實(shí)現(xiàn)。
選取readBytes(byte[] dst, int dstIndex, int length)分析:
首先對(duì)緩沖區(qū)可讀空間進(jìn)行校驗(yàn):如果讀取的長(zhǎng)度(length) < 0,會(huì)拋出IllegalArgumentException異常;如果可讀的字節(jié)數(shù)小于需要讀取的長(zhǎng)度(length),會(huì)拋出IndexOutOfBoundsException異常
校驗(yàn)通過(guò)之后,調(diào)用getBytes方法從當(dāng)前的讀索引開(kāi)始進(jìn)行讀?。ㄟ@一塊就需要由真正的子類(lèi)來(lái)各自實(shí)現(xiàn)),復(fù)制length個(gè)字節(jié)到目標(biāo)byte數(shù)組,數(shù)組開(kāi)始的位置是dstIndex
讀取成功后,對(duì)讀索引進(jìn)行遞增,增加的長(zhǎng)度為length
寫(xiě)操作寫(xiě)操作的公共功能由父類(lèi)實(shí)現(xiàn),差異化由具體的子類(lèi)實(shí)現(xiàn)。
選取writeBytes(byte[] src, int srcIndex, int length)分析:
首先對(duì)緩沖區(qū)的可寫(xiě)空間進(jìn)行校驗(yàn):如果要寫(xiě)入的長(zhǎng)度(length) < 0,會(huì)拋出IllegalArgumentException異常;如果要寫(xiě)入的長(zhǎng)度小于緩沖區(qū)可寫(xiě)入的字節(jié)數(shù),表明可寫(xiě);如果要寫(xiě)入的長(zhǎng)度 > 最大容量 - writeIndex,會(huì)拋出IndexOutOfBoundsException;否則進(jìn)行擴(kuò)容操作(擴(kuò)容操作的原理前面已經(jīng)講過(guò))。
操作索引與索引相關(guān)的操作主要涉及設(shè)置讀寫(xiě)索引、mark、和reset等。
選取readerIndex(int readerIndex)進(jìn)行分析:
首先對(duì)索引合法性進(jìn)行判斷:如果readerIndex小于0或者readerIndex > writeIndex,則拋出IndexOutOfBoundsException異常
校驗(yàn)通過(guò)之后,將讀索引設(shè)置為readerIndex
重用緩沖區(qū)選取discardReadBytes()進(jìn)行分析:
如果readIndex等于0,直接返回
如果readIndex和writeIndex不相等,首先調(diào)用setBytes(int index, ByteBuf src, int srcIndex, int length)方法進(jìn)行字節(jié)數(shù)組的復(fù)制,
然后重新設(shè)置markReadIndex、markWriteIndex、readIndex和writeIndex
如果readIndex等于writeIndex,調(diào)整markReadIndex和markWriteIndex,不進(jìn)行字節(jié)數(shù)組復(fù)制,設(shè)置readIndex=writeIndex=0
skipBytes校驗(yàn)跳過(guò)的字節(jié)長(zhǎng)度:如果跳過(guò)的字節(jié)長(zhǎng)度小于0,則拋出IllegalArgumentException異常,如果跳過(guò)的字節(jié)數(shù)大于可讀取的字節(jié)數(shù),則拋出IndexOutOfBoundsException異常
校驗(yàn)通過(guò)之后,readIndex增加跳過(guò)的字節(jié)長(zhǎng)度
AbstractReferenceCountedByteBuf該類(lèi)主要是對(duì)引用進(jìn)行計(jì)數(shù),類(lèi)似于JVM內(nèi)存回收的對(duì)象引用計(jì)數(shù)器,用于跟蹤對(duì)象的分配和銷(xiāo)毀,做自動(dòng)內(nèi)存回收。
成員變量AtomicIntegerFieldUpdater
volatile int refCnt:用于跟蹤對(duì)象的引用次數(shù),使用volatile是為了解決多線(xiàn)程并發(fā)訪(fǎng)問(wèn)的可見(jiàn)性問(wèn)題。
對(duì)象引用計(jì)數(shù)器每調(diào)用retain()方法一次,引用計(jì)數(shù)器就會(huì)加1,但加完之后會(huì)對(duì)數(shù)據(jù)進(jìn)行校驗(yàn),具體的校驗(yàn)內(nèi)容如下:
如果加1之前的引用次數(shù)小于等于0或者原來(lái)的引用次數(shù) + 增加的次數(shù) < 原來(lái)的引用次數(shù),則需要還原這次引用計(jì)數(shù)器增加操作,并且拋出IllegalReferenceCountException異常
UnpooledHeapByteBuf是基于堆內(nèi)存分配的字節(jié)緩沖區(qū),每次I/O讀寫(xiě)都會(huì)創(chuàng)建一個(gè)新的UnpooledHeapByteBuf。
成員變量ByteBufAllocator alloc:用于UnpooledHeapByteBuf的內(nèi)存分配
byte[] array:緩沖區(qū)數(shù)組,此處也可用ByteBuffer,但是用byte數(shù)組的原因是提升性能和更加便捷的進(jìn)行位操作
ByteBuffer tmpNioBuf:用于實(shí)現(xiàn)Netty的ByteBuf到JDK NIO ByteBuffer的轉(zhuǎn)換
動(dòng)態(tài)擴(kuò)展緩沖區(qū)校驗(yàn)新容量:如果新容量小于0或者新容量大于最大容量,拋出IllegalArgumentException異常,否則校驗(yàn)通過(guò)
如果新容量大于舊容量,使用new byte[newCapacity]創(chuàng)建新的緩沖數(shù)組,然后通過(guò)System.arraycopy進(jìn)行復(fù)制,將舊的緩沖區(qū)內(nèi)容拷貝到新的緩沖區(qū)中,最后在ByteBuf中替換舊的數(shù)組,并且將原來(lái)的ByteBuffer tmpNioBuf置為空
如果新容量小于舊容量,使用new byte[newCapacity]創(chuàng)建新的緩沖數(shù)組,如果讀索引小于新容量(如果寫(xiě)索引大于新容量,將寫(xiě)索引直接置為新容量),然后通過(guò)System.arraycopy將當(dāng)前可讀的緩沖區(qū)內(nèi)容復(fù)制到新的byte數(shù)組,如果讀索引大于新容量,說(shuō)明沒(méi)有可以拷貝的緩沖區(qū),直接將讀寫(xiě)索引置為新容量,并且使用新的byte數(shù)組替換原來(lái)的字節(jié)數(shù)組
字節(jié)數(shù)組復(fù)制setBytes(int index, byte[] src, int srcIndex, int length)
首先是合法性校驗(yàn),先是校驗(yàn)index,length,如果這兩個(gè)值有小于0,或者相加小于0,或者兩個(gè)相加大于ByteBuf的容量,則拋出IndexOutOfBoundsException異常,接著校驗(yàn)被復(fù)制的數(shù)組的長(zhǎng)度和索引問(wèn)題(srcIndex、length),如果srcIndex、length小于0,或者兩個(gè)相加小于0,或者兩個(gè)相加超過(guò)了src字節(jié)數(shù)組的容量,也拋出IndexOutOfBoundsException異常
校驗(yàn)通過(guò)之后,使用System.arraycopy方法進(jìn)行字節(jié)數(shù)組的拷貝
ByteBuf以get和set開(kāi)頭讀寫(xiě)緩沖區(qū)的方法不會(huì)修改讀寫(xiě)索引
轉(zhuǎn)換成JDK ByteBuffer由于UnpooledHeapByteBuf緩沖區(qū)采用了byte數(shù)組實(shí)現(xiàn),同樣的ByteBuffer底層也是用了byte數(shù)組實(shí)現(xiàn),同時(shí)ByteBuffer還提供了wrap方法,
直接將字節(jié)數(shù)組轉(zhuǎn)換成ByteBuffer,最后調(diào)用slice方法。由于每次調(diào)用都會(huì)創(chuàng)建一個(gè)新的ByteBuffer,因此起不到重用緩沖區(qū)內(nèi)容的效果。
hasArray():是否支持?jǐn)?shù)組,判斷緩沖區(qū)的實(shí)現(xiàn)是否基于字節(jié)數(shù)組
array():如果緩沖區(qū)的實(shí)現(xiàn)基于字節(jié)數(shù)組,返回字節(jié)數(shù)組
PooledByteBuf PoolArenaArena是指一塊區(qū)域,在內(nèi)存管理中,Memory Arena指內(nèi)存中的一大塊連續(xù)的區(qū)域,PoolArena是Netty的內(nèi)存池實(shí)現(xiàn)類(lèi)。
為了集中管理內(nèi)存的分配和釋放,同時(shí)提高分配和釋放內(nèi)存的性能,框架會(huì)預(yù)先申請(qǐng)一大塊內(nèi)存,然后通過(guò)提供相應(yīng)的分配和釋放接口來(lái)使用內(nèi)存。由于不再使用系統(tǒng)調(diào)用來(lái)申請(qǐng)和釋放內(nèi)存,
應(yīng)用或者系統(tǒng)的性能大大提高。預(yù)先申請(qǐng)的那一大塊內(nèi)存稱(chēng)之為Memory Arena。
Netty的PoolArena是由多個(gè)Chunk組成的大塊內(nèi)存區(qū)域,每個(gè)Chunk由一個(gè)或者多個(gè)Page組成。因此,對(duì)內(nèi)存的組織管理主要集中在如何組織管理Chunk和Page。
PoolChunkChunk主要用來(lái)組織和管理多個(gè)Page的內(nèi)存分配。Netty中,Chunk中的Page被構(gòu)造成一棵二叉樹(shù)。
每一個(gè)Page可以成為一個(gè)節(jié)點(diǎn),第一層的Page節(jié)點(diǎn)用來(lái)分配所有Page需要的內(nèi)存。每個(gè)節(jié)點(diǎn)記錄了自己在Memory Arena中的偏移地址,當(dāng)一個(gè)節(jié)點(diǎn)代表的內(nèi)存區(qū)域被分配出去以后,
該節(jié)點(diǎn)會(huì)被標(biāo)記為已分配,從這個(gè)節(jié)點(diǎn)往下的所有節(jié)點(diǎn)在后面的內(nèi)存分配請(qǐng)求中都會(huì)被忽略。
在內(nèi)存分配查找節(jié)點(diǎn)時(shí),對(duì)樹(shù)的遍歷采用深度優(yōu)先的算法,但在選擇在哪個(gè)子節(jié)點(diǎn)繼續(xù)遍歷時(shí)則是隨機(jī)的,并不總是訪(fǎng)問(wèn)左邊的子節(jié)點(diǎn)。
PoolSubpage對(duì)于小于一個(gè)Page的內(nèi)存,Netty在Page中完成分配。每個(gè)Page會(huì)被切分成大小相等的多個(gè)存儲(chǔ)塊,存儲(chǔ)塊的大小由第一次申請(qǐng)的內(nèi)存塊大小決定。
一個(gè)Page只能用于分配與第一次申請(qǐng)時(shí)大小相同的內(nèi)存。
Page中存儲(chǔ)區(qū)域的使用狀態(tài)通過(guò)一個(gè)long數(shù)組來(lái)維護(hù),數(shù)組中每個(gè)long的每一位表示一個(gè)塊存儲(chǔ)區(qū)域的占用情況:0表示未占用,1表示已占用。
內(nèi)存回收策略Chunk和Page都通過(guò)狀態(tài)位來(lái)標(biāo)識(shí)內(nèi)存是否可用,不同的是Chunk通過(guò)在二叉樹(shù)上對(duì)節(jié)點(diǎn)進(jìn)行標(biāo)識(shí)實(shí)現(xiàn),Page是通過(guò)維護(hù)塊的使用狀態(tài)標(biāo)識(shí)來(lái)實(shí)現(xiàn)。
PooledDirectByteBufPooledDirectByteBuf基于內(nèi)存池實(shí)現(xiàn)。
創(chuàng)建字節(jié)緩沖區(qū)實(shí)例新創(chuàng)建PooledDirectByteBuf對(duì)象不能直接new,而是從內(nèi)存池Recycler
設(shè)置讀寫(xiě)索引、標(biāo)記讀寫(xiě)索引為0。
copy(int index, int length)方法可以復(fù)制一個(gè)ByteBuf實(shí)例,并且與原來(lái)的ByteBuf相互獨(dú)立。
首先校驗(yàn)索引和長(zhǎng)度的合法性
校驗(yàn)通過(guò)之后,調(diào)用PooledByteBufAllocator分配一個(gè)新的ByteBuf,最終會(huì)調(diào)用PooledByteBufAllocator中的newDirectBuffer(int initialCapacity, int maxCapacity)方法進(jìn)行內(nèi)存的分配
在newDirectBuffer中,直接從緩存中獲取ByteBuf而不是創(chuàng)建一個(gè)新的對(duì)象
ByteBuf輔助類(lèi) ByteBufHolderByteBufHolder是BytBuf容器。比如,Http協(xié)議的請(qǐng)求消息和應(yīng)答消息都可以攜帶消息體,這個(gè)消息體在Netty中就是ByteBuf對(duì)象。由于不同的協(xié)議消息體可以包含不同的
協(xié)議字段和功能,因此需要對(duì)ByteBuf進(jìn)行包裝和抽象,為了滿(mǎn)足這些定制化的需求,Netty抽象出了ByteBufHolder對(duì)象。
ByteBufAllocator是字節(jié)緩沖區(qū)分配器,按照Netty緩沖區(qū)的實(shí)現(xiàn)不同可以分為:基于內(nèi)存池的字節(jié)緩沖區(qū)分配器和普通的字節(jié)緩沖區(qū)分配器。
方法名稱(chēng) | 返回值說(shuō)明 | 功能說(shuō)明 |
---|---|---|
buffer() | ByteBuf | 分配一個(gè)字節(jié)緩沖區(qū),緩沖區(qū)的類(lèi)型由ByteBufAllocator的實(shí)現(xiàn)類(lèi)決定 |
buffer(int initialCapacity) | ByteBuf | 分配一個(gè)初始容量為initialCapacity的字節(jié)緩沖區(qū),緩沖區(qū)的類(lèi)型由ByteBufAllocator的實(shí)現(xiàn)類(lèi)決定 |
buffer(int initialCapacity, int maxCapacity) | ByteBuf | 分配一個(gè)初始容量為initialCapacity,最大容量為maxCapacity的字節(jié)緩沖區(qū),緩沖區(qū)的類(lèi)型由ByteBufAllocator的實(shí)現(xiàn)類(lèi)決定 |
ioBuffer(int initialCapacity, int maxCapacity) | ByteBuf | 分配一個(gè)初始容量為initialCapacity,最大容量為maxCapacity的Direct Buffer,Direct Buffer I/O性能高 |
heapBuffer(int initialCapacity, int maxCapacity) | ByteBuf | 分配一個(gè)初始容量為initialCapacity,最大容量為maxCapacity的Heap Buffer |
directBuffer(int initialCapacity, int maxCapacity) | ByteBuf | 分配一個(gè)初始容量為initialCapacity,最大容量為maxCapacity的Direct Buffer |
compositeBuffer(int maxNumComponents) | CompositeByteBuf | 分配一個(gè)最多包含maxNumComponents個(gè)緩沖區(qū)的復(fù)合緩沖區(qū),緩沖區(qū)的類(lèi)型由ByteBufAllocator的實(shí)現(xiàn)類(lèi)決定 |
isDirectBufferPooled() | boolean | 是否使用了直接內(nèi)存池 |
calculateNewCapacity(int minNewCapacity, int maxCapacity) | int | 動(dòng)態(tài)擴(kuò)容時(shí)計(jì)算新容量 |
CompositeByteBuf允許將多個(gè)ByteBuf的實(shí)例組裝到一起。
CompositeByteBuf定義了一個(gè)Component類(lèi)型的集合,Component實(shí)際上是ByteBuf的包裝實(shí)現(xiàn)類(lèi),它聚合了ByteBuf對(duì)象,維護(hù)ByteBuf在集合中的位置偏移量等信息。
CompositeByteBuf支持動(dòng)態(tài)增加(addComponent(ByteBuf buffer))和刪除(removeComponent(int cIndex))ByteBuf,增加或刪除ByteBuf之后,
需要更新各個(gè)ByteBuf的索引偏移量。
ByteBufUtil提供了大量的靜態(tài)方法來(lái)操作ByteBuf。列舉三個(gè):
ByteBuf encodeString(ByteBufAllocator alloc, CharBuffer src, Charset charset):對(duì)需要編碼的字符串src按照指定的字符集charset進(jìn)行編碼,利用指定的ByteBufAllocator生成一個(gè)ByteBuf
decodeString(ByteBuf src, int readerIndex, int len, Charset charset):從指定索引readIndex開(kāi)始往后len個(gè)字節(jié)長(zhǎng)度,對(duì)ByteBuf對(duì)象src按照指定的字符集charset進(jìn)行解碼
hexDump(ByteBuf buffer):將ByteBuf對(duì)象的參數(shù)內(nèi)容以十六進(jìn)制的格式輸出
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/72361.html
摘要:轉(zhuǎn)發(fā)自 轉(zhuǎn)發(fā)自 http://netty.io/wiki/referenc... Since Netty version 4, the life cycle of certain objects are managed by their reference counts, so that Netty can return them (or their shared resources)...
摘要:根據(jù)對(duì)的定義即所謂的就是在操作數(shù)據(jù)時(shí)不需要將數(shù)據(jù)從一個(gè)內(nèi)存區(qū)域拷貝到另一個(gè)內(nèi)存區(qū)域因?yàn)樯倭艘淮蝺?nèi)存的拷貝因此的效率就得到的提升在層面上的通常指避免在用戶(hù)態(tài)與內(nèi)核態(tài)之間來(lái)回拷貝數(shù)據(jù)例如提供的系統(tǒng)調(diào)用它可以將一段用戶(hù)空間內(nèi)存映射到內(nèi) 根據(jù) Wiki 對(duì) Zero-copy 的定義: Zero-copy describes computer operations in which the C...
摘要:提供了作為它的字節(jié)容器但是這個(gè)類(lèi)使用起來(lái)過(guò)于復(fù)雜而且也有些繁瑣的的代替品是的的數(shù)據(jù)處理通過(guò)兩個(gè)組件暴露下面是的優(yōu)點(diǎn)它可以被用戶(hù)自定義的緩沖區(qū)類(lèi)擴(kuò)展通過(guò)內(nèi)置的復(fù)合緩沖區(qū)類(lèi)型實(shí)現(xiàn)了透明的零拷貝容量可以按需增長(zhǎng)在讀和寫(xiě)這兩種模式之間雀環(huán)不需要調(diào)用 Java NIO 提供了 ByteBuffer 作為它的字節(jié)容器, 但是這個(gè)類(lèi)使用起來(lái)過(guò)于復(fù)雜, 而且也有些繁瑣. Netty 的 ByteBuf...
摘要:使用來(lái)優(yōu)化套接字操作,盡可能消除由的緩沖區(qū)實(shí)現(xiàn)所導(dǎo)致的性能以及內(nèi)存使用率的懲罰,這種優(yōu)化發(fā)生在的核心代碼中,不會(huì)被暴露出來(lái)。當(dāng)前將會(huì)被增加所寫(xiě)入的字節(jié)數(shù)。 ByteBuf是Java NIO ByteBuffer的替代品,是網(wǎng)絡(luò)數(shù)據(jù)基本單位字節(jié)的容器。 ByteBuf的API Netty的數(shù)據(jù)處理API通過(guò)兩個(gè)組件暴漏:抽象類(lèi)ByteBuf和接口ByteBufHolder ByteBuf...
摘要:當(dāng)你從讀取時(shí),它的將會(huì)被遞增已經(jīng)被讀取的字節(jié)數(shù)。達(dá)到和位于同一位置,表示我們到達(dá)可以讀取的數(shù)據(jù)的末尾。該應(yīng)用程序可以選擇為多個(gè)消息重用相同的消息主體。 ByteBuffer 當(dāng)我們進(jìn)行數(shù)據(jù)傳輸?shù)臅r(shí)候,往往需要使用到緩沖區(qū),常用的緩沖區(qū)就是JDK NIO類(lèi)庫(kù)提供的java.nio.Buffer。 showImg(https://segmentfault.com/img/bVbbz8p?w...
閱讀 1677·2021-11-12 10:35
閱讀 1618·2021-08-03 14:02
閱讀 2691·2019-08-30 15:55
閱讀 2033·2019-08-30 15:54
閱讀 768·2019-08-30 14:01
閱讀 2432·2019-08-29 17:07
閱讀 2259·2019-08-26 18:37
閱讀 3039·2019-08-26 16:51