netty之channelbuffer

看过英文的文档源码,还是勉强解释下,分享

 ChannelBuffer的实现类有多个,这里列举其中主要的几个:

  1)HeapChannelBuffer:这是Netty读网络数据时默认使用的ChannelBuffer,这里的Heap就是Java堆的意 思,因为 读SocketChannel的数据是要经过ByteBuffer的,而ByteBuffer实际操作的就是个byte数组,所以 ChannelBuffer的内部就包含了一个byte数组,使得ByteBuffer和ChannelBuffer之间的转换是零拷贝方式。根据网络字 节续的不同,HeapChannelBuffer又分为BigEndianHeapChannelBuffer和 LittleEndianHeapChannelBuffer,默认使用的是BigEndianHeapChannelBuffer。Netty在读网络 数据时使用的就是HeapChannelBuffer,HeapChannelBuffer是个大小固定的buffer,为了不至于分配的Buffer的 大小不太合适,Netty在分配Buffer时会参考上次请求需要的大小。

  2)DynamicChannelBuffer:相比于HeapChannelBuffer,DynamicChannelBuffer可动态自适 应大 小。对于在DecodeHandler中的写数据操作,在数据大小未知的情况下,通常使用DynamicChannelBuffer。

  3)ByteBufferBackedChannelBuffer:这是directBuffer,直接封装了ByteBuffer的 directBuffer。

  对于读写网络数据的buffer,分配策略有两种:1)通常出于简单考虑,直接分配固定大小的buffer,缺点是,对一些应用来说这个大小限制有 时是不 合理的,并且如果buffer的上限很大也会有内存上的浪费。2)针对固定大小的buffer缺点,就引入动态buffer,动态buffer之于固定 buffer相当于List之于Array。

  buffer的寄存策略常见的也有两种(其实是我知道的就限于此):1)在多线程(线程池) 模型下,每个线程维护自己的读写buffer,每次处理新的请求前清空buffer(或者在处理结束后清空),该请求的读写操作都需要在该线程中完成。 2)buffer和socket绑定而与线程无关。两种方法的目的都是为了重用buffer。

  Netty对buffer的处理策略是:读 请求数据时,Netty首先读数据到新创建的固定大小的HeapChannelBuffer中,当HeapChannelBuffer满或者没有数据可读 时,调用handler来处理数据,这通常首先触发的是用户自定义的DecodeHandler,因为handler对象是和ChannelSocket 绑定的,所以在DecodeHandler里可以设置ChannelBuffer成员,当解析数据包发现数据不完整时就终止此次处理流程,等下次读事件触 发时接着上次的数据继续解析。就这个过程来说,和ChannelSocket绑定的DecodeHandler中的Buffer通常是动态的可重用 Buffer(DynamicChannelBuffer),而在NioWorker中读ChannelSocket中的数据的buffer是临时分配的 固定大小的HeapChannelBuffer,这个转换过程是有个字节拷贝行为的。

  对ChannelBuffer的创建,Netty内部使用的是ChannelBufferFactory接口,具体的实现有 DirectChannelBufferFactory和HeapChannelBufferFactory。对于开发者创建 ChannelBuffer,可使用实用类ChannelBuffers中的工厂方法。

你可能感兴趣的:(netty之channelbuffer)