io.netty.buffer包中是netty ByteBuf的實現。ByteBuf是一個二進制緩衝區的抽象接口,它的功能有:html
緩衝區的使用範圍很是普遍:I/O操做,序列化/反序列化,編碼轉換,壓縮/解壓,加/解密等全部須要使用byte[]的場景。 有些場景須要須要可以快速地建立和銷燬緩衝區,如:高併發的服務器,處理請求、返回響應的時時候須要大量且高頻地建立,銷燬緩衝區。 有些場景不能肯定須要多大的緩衝區,如: 從數據流中分離出一條消息,消息的長度不肯定,只知道最大長度。假如消息的最大長度是64KB,而消息的平均長度只有4KB, 若是每次建立64KB的緩衝區就太浪費了。若是緩衝區可以在須要的時候自動且高效地增減容量,就完美了。 在全部的場景中都涉及到頻繁的數據copy,這要求緩衝區數據copy的性能要儘可能高。若是有可能,儘可能減小數據copy。 ByteBuf就是爲解決以上問題而設計的。java
以下所示算法
| discardable bytes | readable bytes | writable bytes | 0 readerIndex writerIndex capacity
| readable bytes | writable bytes | readerIndex(0) writerIndex capacity
對二進制數據的讀寫是ByteBuf的核心能力。它提供兩種讀寫方式:服務器
ByteBuf爲了方便使用,提供了一些基本數據類型(unsigned表示無符號類型)的讀寫支持:網絡
數據類型 | 長度(Byte) |
---|---|
byte, unsignedByte | 1 |
short, unsignedShort | 2 |
char | 2 |
medium, unsignedMedium | 3 |
int, unsignedInt | 4 |
long | 8 |
float | 4 |
double | 8 |
對這些基本數據類型的讀寫涉及到了字節須的問題,ByteBuf支持兩種字節序,使用java.nio.ByteOrder中的定義,默認的字節序是BIG_ENDIAN, 這個也是網絡字節序。併發
此外還提供了對byte[]類型及能夠當成byte[]使用的數據類型的支持, 方法名都是:getBytes,setBytes, readBytes, writeBytes。app
內存管理分爲兩個部分:內存分配,內存釋放。 ByteBufAllocator是內存分配的接口,它有兩個具體實現:UnpooledByteBufAllocator, PooledByteBufAllocator。 UnpooledByteBufAllocator是JVM內存分配接口的簡單封裝。 PooledByteBufAllocator在JVM內存分配的基礎上實現了一套獨立的內存分配算法。 內存釋放的關鍵是如何斷定對象死亡,ByteBuf繼承了ReferenceCounted接口,使用引用計數的方式斷定對象死亡。高併發
PooledByteBufAllocator中高效的內存管理算法是ByteBuf的性能基礎,理解了它的算法是理解ByteBuf的關鍵。工具
graph TD; B[ByteBuf]-->AB[AbstractByteBuf]; B-->SB[SwappedByteBuf]; B-->WB[WrappedByteBuf]; AB[AbstractByteBuf]-->ARCB[AbstractReferenceCountedByteBuf]; ARCB-->CB[CompositeByteBuf<br>FixedCompositeByteBuf]; ARCB-->PB[PooledByteBuf<T>]; ARCB-->UBB[UnpooledDirectByteBuf<br>UnpooledHeapByteBuf<br>UnpooledUnsafeDirectByteBuf<br>UnpooledUnsafeHeapByteBuf<br>UnpooledUnsafeNoCleanerDirectByteBuf]; ARCB-->ROBB[ReadOnlyByteBufferBuf]; PB[PooledByteBuf<T>]-->PDB[PooledDirectByteBuf]; PB-->PUDB[PooledUnsafeDirectByteBuf]; PB-->PHB[PooledHeapByteBuf]; PHB-->PUHB[PooledUnsafeHeapByteBuf];
上圖是ByteBuf體系結構中主要的類和接口。主要分爲三大類:性能
CompositeByteBuf, FixedCompositeByteBuf: 把不一樣的ByteBuf組合成一個ByteBuf。 PooledByteBuf:實現了自定義內存管理算法的。 UnpooledXXXX: 直接使用JVM內存管理能力。 ReadOnlyByteBufferBuf: 只讀的。
有兩個工具類幫助開發者使用ByteBuf:
使用ByteBufUtil.DEFAULT_ALLOCATOR獲得ByteBufAllocator實例。這個實例多是UnpooledByteBufAllocator,也多是PooledByteBufAllocator類型,這取決於io.netty.allocator.type屬性的設置。默認是unpooled,UnpooledByteBufAllocator類型。若是想要PooledByteBufAllocator類型,把這個屬性的值設置成pooled: java -Dio.netty.allocator.type=pooled,或者System.setProperty("io.netty.allocator.type", "pooled")
netty不建議直接建立建立ByteBuf實例,推薦使用ByteBufAllocator建立ByteBuf實例,或者使用Unpooled靜態方法。 ByteBufAllocator有7種方法用於建立ByteBuf實例:
方法名 | 特性 |
---|---|
buffer | 使用多是JVM堆內存或直接內存,取決於具體的實現 |
ioBuffer | 若是能夠的話優先使用直接內存 |
heapBuffer | 使用堆內存 |
directBuffer | 使用直接內存 |
CompositeByteBuf | 使用多是JVM堆內存或直接內存,取決於具體的實現 |
compositeHeapBuffer | 使用堆內存 |
compositeDirectBuffer | 使用堆內存 |
Unpooled建立ByteBuf實例的方法有2兩種:
方法名 | 特性 |
---|---|
buffer | 使用堆內存 |
directBuffer | 使用直接內存 |
Unpooled提供了一系列的wrappedBuffer方法,把一些數據類型包裝成一個ByteBuf, 這些數據類型有:
wrappedBuffer方法還能夠把byte[].., ByteBuffer.., ByteBuf..包裝成一個CompositeByteBuf。
數據讀寫是ByteBuf的基本功能,前面已經講過,相關方法是: getXXX, readXXX, setXXX, writeXXX。
原文出處:https://www.cnblogs.com/brandonli/p/11534491.html