netty ChannelBuffer

       ChannelBuffer是netty自己的缓冲区,用于替代nio的Buffer,这种替代具有显著的优势,解决了Buffer存在的一些问题,满足了日常网络应用程序开发的需求。具有以下特点:

  1. 如果必要的话,可以定义自己的ChannelBuffer。
  2. 通过复合缓冲区CompositeChannelBuffer实现透明的零拷贝”Zero-Copy-Capable”。
  3. 提供了一个开箱即用的动态缓冲区DynamicChannelBuffer,其容量可动态扩大,就像StringBuffer。
  4. 不用在使用flip()进行读写反转了。
  5. 通常比ByteBuffer快。
       零拷贝”Zero-Copy-Capable”机制是指在TCP/IP传输层接收到的多个数据包(一个数据包封装为一个 ChannelBuffer),在应用层组成了一个完整的协议报文数据,传统上,数据是从多个包结合将它们复制到一个新的字节缓冲区,而零拷贝组合已有缓冲区为一个对外透明的缓冲区,提供给应用层使用,从而消除了缓冲区的复制。如下图所示:
其类图如下:
 



  
一、属性
  1. readerIndex,读指针。
  2. writerIndex,写指针。
  3. markedReaderIndex,读标志位。
  4. markedWriterIndex,写标志位。
其中:0<=readerIndex<=writerIndex<=capacity()
markWriterIndex():markedWriterIndex = writerIndex  resetWriterIndex():writerIndex = markedWriterIndex;
markReaderIndex():markedReaderIndex = readerIndex  resetReaderIndex():readerIndex = markedReaderIndex;
HeapChannelBuffer跟NIO HeapByteBuffer作用相当,内部包含属性byte[] array,在堆上建立缓冲区。它有两个子类:BigEndianHeapChannelBufferLittleEndianHeapChannelBuffer。这里有个很基础的概念:字节序(ByteOrder/Endianness),字节序规定了多于一个字节的数字,如何在内存中表示。BIG_ENDIAN(大端序)表示高位在前,按照大端序,整型数12会被存储为0 0 0 12这样四个字节,而LITTLE_ENDIAN则正好相反。
 
DynamicChannelBuffer是动态缓冲区,它实现自动扩容的核心在于ensureWritableBytes方法,算法很简单:在写入前做容量检查,容量不够时,新建一个容量x2的buffer。包含属性ChannelBufferFactory factory,ByteOrder endianness,ChannelBuffer buffer。
 
CompositeChannelBuffer:A virtual buffer which shows multiple buffers as a single merged buffer。包含属性ByteOrder order,ChannelBuffer[] components,int[] indices,int lastAccessedComponentId,boolean gathering。其中indices.length = components.length+1, indices[i]: 若i<components.length,值为components[i]的readerIndex在整个CompositeChannelBuffer中index位置;若i=components.length,值为整个CompositeChannelBuffer的capacitylastAccessedComponentId指向整个CompositeChannelBuffer的readerIndex或writerIndex当前所在的components位置。
 
ByteBufferBackedChannelBuffer封装了NIO ByteBuffer的类,用于实现堆外内存的Buffer(使用NIO的DirectByteBuffer),当然它也可以放其他的ByteBuffer的实现类。包含属性ByteBuffer buffer,ByteOrder order,int capacity。
 

WrappedChannelBuffer都是几个对已有ChannelBuffer进行包装,完成特定功能的类。

类名 入口 功能
SlicedChannelBuffer ChannelBuffer.slice()
ChannelBuffer.slice(int,int)
某个ChannelBuffer的一部分
TruncatedChannelBuffer slice(int index, int length) 某个ChannelBuffer的一部分, 可以理解为其实位置为0的SlicedChannelBuffer
DuplicatedChannelBuffer ChannelBuffer.duplicate() 与某个ChannelBuffer使用同样的存储, 区别是有自己的index
ReadOnlyChannelBuffer ChannelBuffers
.unmodifiableBuffer(ChannelBuffer)
不可变的buffer
  二、构造ChannelBuffer
通过工具类 ChannelBuffers的静态方法来构造各种 ChannelBuffer。