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