1. 内容概要
1.1 总结
1.1.1 内存管理
Netty 使用的是堆外内存,需要手动释放,使用引用计数的方式管理内存,当引用计数 =0,回收ByteBuf 底层内存
原则:谁使用retain() , 谁释放release()
1.1.2 创建ByteBuf的方式
- ByteBuf buffer = ctx.alloc().buffer(); (第6章,P41)
- ByteBuf buffer = ByteBufAllocator.DEFAULT.buffer(9, 100);(第7章,P49)
2. 课程内容
1 ByteBuf 的结构
- ByteBuf 容器 - 当前容量 capacity = 已废弃的字节 + 可读字节 + 可写字节
- ByteBuf 容器 - 最大容量 maxCapacity = capacity + 可扩容字节
- 被读写指针划分三部分
- 从指针开始的地方读写,读写之间相互没有冲突
- 已废弃的字节(通常为0)
1.1 readerIndex
- 读指针,从0开始
- ByteBuf 中每读一个字节,readerIndex自增1
- 可读字节数 = writerIndex - readerIndex , 所以writeIndex = readerIndex,ByteBuf 不可读
1.2 writerIndex
- 写指针,从0开始
- ByteBuf中每写一个字节,writerIndex自增1,直到 capacity
- 可写字节数 = capacity - writeIndex
1.3 扩容
- ByteBuf 写数据,容量不足就会自动扩容
- capacity 扩容到 maxCapacity
- 超过maxCapacity会报错
2 常用 API
API类别 | 名称 | 使用 |
容量 | capacity() | 当前ByteBuf容量 capacity = 已废弃的字节 + 可读字节 + 可写字节 |
maxCapacity() | 最大容量= capacity + 可扩容字节 | |
readableBytes() | ByteBuf当前可读字节数,= writerIndex - readerIndex | |
isReadable() | 是否可读 | |
writableBytes() | ByteBuf当前可写字节数,= capacity - writeIndex | |
isWritable() | 是否可写 | |
MaxWritableBytes() | 最大可写字节数,= maxCapacity - writeIndex | |
读写指针 | readerIndex() | 返回当前读指针readerIndex |
readerIndex(int) | 设置读指针index | |
writerIndex() | 返回当前写指针writerIndex | |
writerIndex(int) | 设置写指针index | |
markReaderIndex() | 保存当前读指针(推荐) | |
resetReaderIndex() | 把当前读指针恢复到之前保存的值(推荐) | |
markWriterIndex() | 保存当前写指针(推荐) | |
resetWriterIndex() | 把当前写指针恢复到之前保存的值(推荐) | |
读写 | readBytes(byte[] dst) | 把ByteBuf中的数据全部读取到dst |
writeBytes(byte[] src) | 将src中的数据写入到ByteBuf | |
readByte() | 从ByteBuf中读取一个字节 | |
writeByte(byte b) | 往ByteBuf写入一个字节 | |
retain() | 引用计数加1 | |
release() | 引用计数减1 | |
slice() | 截取readerIndex到writeIndex的数据,返回最大容量为原始ByteBuf的readableBytes()的ByteBuf | |
duplicate() | 共享原始ByteBuf,书本确实示例,后期补全 | |
copy() | 复制原始ByteBuf,返回的ByteBuf写数据不影响原始ByteBuf | |
retainedSlice() | 等价于slice().retain(),需要调用一次release(),否则报错 | |
retainedDuplicate | 等价于duplicate().retain(),需要调用一次release(),否则报错 | |