- Netty 的 ByteBuffer 替代品是 ByteBuf ,既解决了 JDK API 的局限性,又为网络应用程序的开发者提供了更好的 API。通过两个组件
abstract class ByteBuf
和interface ByteBufHolder
暴露- 它可以被用户自定义的缓冲区类型扩展
- 通过内置的复合缓冲区类型实现了透明的零拷贝
- 容量可以按需增长(类似于 JDK 的 StringBuilder)
- 在读和写这两种模式之间切换不需要调用 ByteBuffer 的 flip()方法
- 读和写使用了不同的索引
- 支持方法的链式调用
- 支持引用计数
- 支持池化
- ByteBuf 维护了读取和写入索引,以 read 或 write 开头的 ByteBuf 方法,会推进索引,而以 set 或 get 开头的方法不会
- ByteBuf 的使用模式
- 堆缓冲区:将数据存储在 JVM 的堆空间中,作为支撑数组,在没有使用池化的情况下可快速分配和释放
- 直接缓冲区:常规的IO操作是将堆缓冲区的内容复制到直接缓冲区中进行IO,直接缓冲区的分配和释放都比较昂贵,对于IO之外的操作,需要将数据复制到堆中
- 复合缓冲区:通过为多个 ByteBuf 提供一个聚合视图,并且可以包含直接内存分配和非直接内存分配
- 派生缓冲区创建成本低廉和源缓冲区共享存储内容,只是具有自己的读、写和标记索引,``duplicate, slice, Unpooled.unmodifiableBuffer, order, readSlice```这些方法会返回派生缓冲区,如果需要真实副本则应该使用 copy
-
ByteBufHolder
提供了缓冲区池化等高级技术,content
返回这个ByteBufHolder
所持有的 ByteBuf,copy
返回这个ByteBufHolder
的一个深拷贝,包括一个其所包含的 ByteBuf 的非共享拷贝,duplicate
返回这个ByteBufHolder
的一个浅拷贝,包括一个其所包含的 ByteBuf 的共享拷贝 -
ByteBufAllocator
接口提供了分配 ByteBuf 的方法,在Channel
和ChannelHandlerContext
都可以获取到ByteBufAllocator
的引用channel.alloc(); ctx.alloc();
;Netty 提供了两种ByteBufAllocator
的实现:PooledByteBufAllocator
和UnpooledByteBufAllocator
,前者池化了 ByteBuf 实例(采用jemalloc),后者非池化,并且每次都会返回一个新的实例,Unpooled
工具类可用来辅助创建未池化的 ByteBuf 实例 -
ByteBufUtil
提供了用于操作 ByteBuf 的静态的辅助方法(与池化无关),其中hexdump
将ByteBuf内容以十六进制打印,equals
用来判断两个 ByteBuf 实例的相等性 - Netty 在第4版中为 ByteBuf 和 ByteBufHolder 引入了引用计数技术,都实现了
ReferenceCounted
接口,只要引用计数大于0,就能保证对象不会被释放;减少到0就会被释放,这对于池化实现能降低内存分配的开销。
网友评论