ByteBuf
readerIndex
,读索引
writerIndex
,写索引
capacity
,当前容量
maxCapacity
,最大容量,当 writerIndex
写入超过 capacity
时,可自动扩容。每次扩容的大小,为 capacity
的 2 倍。当然,前提是不能超过 maxCapacity
大小
readerIndex
<= writerIndex
<= capacity
<= maxCapacity
0~readerIndex ,废弃段 , 一般情况下可理解为已读的部分
readerIndex~writerIndex , 可读段, 可通过 #readXXX()
方法,顺序向下读取
writerIndex~capacity , 可写段, 可通过 #writeXXX()
方法,顺序向下写入
markReaderIndex
.markWriterIndex
- 通过对应的
#markReaderIndex()
和#markWriterIndex()
方法,分别标记读取和写入位置。 - 通过对应的
#resetReaderIndex()
和#resetWriterIndex()
方法,分别读取和写入位置到标记处。
ByteBuf有8个最核心的子类实现
- 按照内存类型分类
- 堆内存字节缓冲区 ( HeapByteBuf ):底层为 JVM 堆内的字节数组,其特点是申请和释放效率较高。但是如果要进行 Socket 的 I/O 读写,需要额外多做一次内存复制,需要将堆内存对应的缓冲区复制到内核 Channel 中,性能可能会有一定程度的损耗。
- 直接内存字节缓冲区 ( DirectByteBuf ):堆外内存,为操作系统内核空间的字节数组,它由操作系统直接管理和操作,其申请和释放的效率会慢于堆缓冲区。但是将它写入或者从 SocketChannel 中读取时,会少一次内存复制,这样可以大大提高 I/O 效率,实现零拷贝。
- 按照 对象池 分类:
- 基于对象池 ( PooledByteBuf )
- 不使用对象池 ( UnpooledByteBuf ):对象池的管理和维护会比较困难,所以在不需要创建大量缓冲区对象时,推荐使用此类缓冲区。
- 按照 Unsafe 分类