ByteBuf类继承关系图以下:java
ReferenceCounted:对象引用计数器,初始化ReferenceCounted对象时,引用数量refCnt为1,调用retain()可增长refCnt,release()用于减小refCnt。refCnt为1时,说明对象实际不可达,release()方法将当即调用deallocate()释放对象。若是refCnt为0,说明对象被错误的引用。在AbstractReferenceCountedByteBuf源码分析小节将详细介绍ReferenceCounted的原理。后端
ByteBuf:实现接口ReferenceCounted和Comparable,实现ReferenceCounted使得ByteBuf具有引用计数的能力,方便跟踪ByteBuf对象分配和释放。数组
EmptyByteBuf:用于构建空ByteBuf对象,capacity和maxCapacity均为0。网络
ReplayingDecoderBuffer:用于构建在IO阻塞条件下实现无阻塞解码的特殊ByteBuf对象,当要读取的数据还未接收彻底时,抛出异常,交由ReplayingDecoder处理。并发
SwappedByteBuf:用于构建具备切换字节顺序功能的ByteBuf对象,默认ByteBuf对象使用BIG_ENDIAN(大字节序)存储数据,SwappedByteBuf能够在BIG_ENDIAN和LITTLE_ENDIAN之间自由切换。TCP/IP各层协议均采用网络字节序(BIG_ENDIAN),关于字节序的更多内容不详细介绍。app
WrappedByteBuf:用于装饰ByteBuf对象,主要有AdvancedLeakAwareByteBuf、SimpleLeakAwareByteBuf和UnreleasableByteBuf三个子类。这里WrappedByteBuf使用装饰者模式装饰ByteBuf对象,AdvancedLeakAwareByteBuf用于对全部操做记录堆栈信息,方便监控内存泄漏;SimpleLeakAwareByteBuf只记录order(ByteOrder endianness)的堆栈信息;UnreleasableByteBuf用于阻止修改对象引用计数器refCnt的值。ide
AbstractByteBuf:提供ByteBuf的默认实现,同时组合ResourceLeakDetector和SwappedByteBuf的能力,ResourceLeakDetector是内存泄漏检测工具,SwappedByteBuf用于字节序不一样时转换字节序。高并发
AbstractDerivedByteBuf:提供派生ByteBuf的默认实现,主要有DuplicatedByteBuf、ReadOnlyByteBuf和SlicedByteBuf。工具
DuplicatedByteBuf使用装饰者模式建立ByteBuf的复制对象,使得复制后的对象与原对象共享缓冲区的内容,可是独立维护本身的readerIndex和writerIndex。部分源码以下:源码分析
private final ByteBuf buffer; public DuplicatedByteBuf(ByteBuf buffer) { super(buffer.maxCapacity()); //共享缓冲区内容 if (buffer instanceof DuplicatedByteBuf) { this.buffer = ((DuplicatedByteBuf) buffer).buffer; } else { this.buffer = buffer; } //调用自身的setIndex方法维护readerIndex和writerIndex setIndex(buffer.readerIndex(), buffer.writerIndex()); } //全部操做都是经过调用被装饰对象buffer的相应方法实现 @Override public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) { buffer.getBytes(index, dst, dstIndex, length); return this; } @Override public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { buffer.getBytes(index, dst, dstIndex, length); return this; }
ReadOnlyByteBuf使用装饰者模式建立ByteBuf的只读对象,该只读对象与原对象共享缓冲区的内容,可是独立维护本身的readerIndex和writerIndex,以后全部的写操做都被限制;部分源码以下:
private final ByteBuf buffer; public ReadOnlyByteBuf(ByteBuf buffer) { super(buffer.maxCapacity()); if (buffer instanceof ReadOnlyByteBuf || buffer instanceof DuplicatedByteBuf) { this.buffer = buffer.unwrap(); } else { this.buffer = buffer; } setIndex(buffer.readerIndex(), buffer.writerIndex()); } @Override protected void _setLong(int index, long value) { throw new ReadOnlyBufferException(); } @Override public int setBytes(int index, InputStream in, int length) { throw new ReadOnlyBufferException(); }
SlicedByteBuf使用装饰者模式建立ByteBuf的一个子区域ByteBuf对象,返回的ByteBuf对象与当前ByteBuf对象共享缓冲区的内容,可是维护本身独立的readerIndex和writerIndex,容许写操做。
AbstractReferenceCountedByteBuf:提供修改对象引用计数器相关操做的默认实现。
CompositeByteBuf:用于将多个ByteBuf组合在一块儿,造成一个虚拟的ByteBuf对象,支持读写和动态扩展。内部使用List<Component>组合多个ByteBuf。推荐使用ByteBufAllocator的compositeBuffer()方法,Unpooled的工厂方法compositeBuffer()或wrappedBuffer(ByteBuf... buffers)建立CompositeByteBuf对象。
FixedCompositeByteBuf:用于将多个ByteBuf组合在一块儿,造成一个虚拟的只读ByteBuf对象,不容许写入和动态扩展。内部使用Object[]将多个ByteBuf组合在一块儿,一旦FixedCompositeByteBuf对象构建完成,则不会被更改。
PooledByteBuf<T>:基于内存池的ByteBuf,主要为了重用ByteBuf对象,提高内存的使用效率;适用于高负载,高并发的应用中。主要有PooledDirectByteBuf,PooledHeapByteBuf,PooledUnsafeDirectByteBuf三个子类,PooledDirectByteBuf是在堆外进行内存分配的内存池ByteBuf,PooledHeapByteBuf是基于堆内存分配内存池ByteBuf,PooledUnsafeDirectByteBuf也是在堆外进行内存分配的内存池ByteBuf,区别在于PooledUnsafeDirectByteBuf内部使用基于PlatformDependent相关操做实现ByteBuf,具备平台相关性。
ReadOnlyByteBufferBuf:只读ByteBuf,内部持有ByteBuffer对象,相关操做委托给ByteBuffer实现,该ByteBuf限内部使用,ReadOnlyByteBufferBuf还有一个子类ReadOnlyUnsafeDirectByteBuf。
UnpooledDirectByteBuf:在堆外进行内存分配的非内存池ByteBuf,内部持有ByteBuffer对象,相关操做委托给ByteBuffer实现。
UnpooledHeapByteBuf:基于堆内存分配非内存池ByteBuf,即内部持有byte数组。
UnpooledUnsafeDirectByteBuf:与UnpooledDirectByteBuf相同,区别在于UnpooledUnsafeDirectByteBuf内部使用基于PlatformDependent相关操做实现ByteBuf,具备平台相关性。
到此,ByteBuf继承家族的各个成员对应的相关功能已介绍完成。
总结:
从内存分配角度看,ByteBuf主要分为两类:
经验代表,在I/O通讯线程的读写缓冲区使用DirectByteBuf,后端业务消息的编解码模块使用HeapByteBuf,这样组合能够达到性能最优。
从内存回收角度看,ByteBuf也分为两类:
本节重点介绍ByteBuf继承家族的各个成员,详细功能后续将经过源码讲解,下一节介绍AbstractByteBuf源码。
欢迎指出本文有误的地方,转载请注明原文出处https://my.oschina.net/7001/blog/743240