ByteBuf主要分为三类:基于byte[]的heapBuffer、基于ByteBuffer的directBuffer和由单一类型(heap or direct)复合而成的compositeBuffer, 因此分配方式也主要分为三种。
- buffer()、buffer(int initialCapacity)、buffer(int initialCapacity, int maxCapacity):在默认情况下分配heapBuffer;如果显示配置directByDefault为true并且程序运行的系统环境(非andriod)支持内存映射则分配directBuffer。
- ioBuffer()、ioBuffer(int initialCapacity)、ioBuffer(int initialCapacity, int maxCapacity):如果程序运行的系统环境支持内存映射则分配directBuffer(注意,这里不关心directByDefault的值),否则分配heapBuffer。
- compositeBuffer()、compositeBuffer(int maxNumComponents):分配一个由单一类型(heap or direct)复合而成的compositeBuffer,heap/direct选择选择与上面两种一致。
分配流程
> 以上三种分配方式的分配流程基本一致,都是现在AbstractByteBufAllocator中,预留了具体的分配方法newHeapBuffer(int initialCapacity, int maxCapacity)和newDirectBuffer(int initialCapacity, int maxCapacity)由子类PooledByteBufAllocator、UnpooledByteBufAllocator实现。
- AbstractByteBufAllocator中的属性
- private static final int DEFAULT_INITIAL_CAPACITY = 256; 初始化容量的缺省值。
- private static final int DEFAULT_MAX_COMPONENTS = 16; compositeBuffer最大ByteBuf数量的缺省值。
- private final boolean directByDefault; 是否默认使用directBuffer。
- private final ByteBuf emptyBuf; 空Buffer,当分配时初始化容量和最大容量都为0时返回。
- AbstractByteBufAllocator中的分配流程
- 校验directByDefault和系统配置以确定分配heapBuffer或directBuffer。
- 校验initialCapacity和maxCapacity是否都为0,如果是则直接返回emptyBuf。
- 校验initialCapacity<0 || initialCapacity>maxCapacity则抛出异常。
- 执行具体的newHeapBuffer()/newDirectBuffer()方法。
- UnpooledByteByfAllocator中的分配流程
- newHeapBuffer()
- 分配并返回一个UnpooledHeapByteBuf,实际是一个byte数组的包装类。
- newDirectBuffer()
- 如果程序运行时是否能获取到sun.misc.Unsafe对象,如果能则分配并返回UnpooledUnsafeDirectBuffer,否则分配返回UnpooledDirectBuffer。
- UpooledUnsafeDirectBuffer和UnpooledDirectBuffer的区别是前者持有内存地址,在做数据处理市可以通过Unsafe对象直接操作内存,后者只能通过nio的ByteBuffer进行操作,前者效率更高。
- newHeapBuffer()
UnpooledByteBuf的分配相对简单,后续章节详解Netty中PooledByteBuf的分配、释放流程以及Netty的缓存技术。