ByteBuf

Posted bbbbs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ByteBuf相关的知识,希望对你有一定的参考价值。

一. 原理

1. ByteBuf维护了两个不同的索引:一个用于读取readerIndex,一个用于写入writerIndex;

2. 以read或者write开头的ByteBuf方法将会推进其对应的索引,以set或get开头的操作则不会;

二. 使用模式

1. 堆缓冲区

最常用的ByteBuf模式是将数据存储在JVM的堆空间中,这种模式被称为支撑数组,它能在没有使用池化的情况下提供快速的分配和释放;

通过套接字发送它之前,JVM会在内部把缓冲区复制到一个直接缓冲区中;

2. 直接缓冲区

内容驻留在常规的会被垃圾回收的堆之外;

相对于堆缓冲区,分配和释放更为昂贵;

3. 复合缓冲区

为多个ByteBuf提供一个聚合视图,通过ByteBuf的子类CompositeByteBuf来实现,CompositeByteBuf中的实例可能同时包含直接内存分配和非直接内存分配;

三. 字节级操作

1. 访问索引

ByteBuf的索引是从0开始的,最后一个索引为capa() - 1;通过ByteBuf.getByte(int index)获取index位置的byte;

2. 丢弃字节

discardReadBytes() 丢弃字节并回收空间;

调用后可读字节部分会移动到缓冲区的开始位置,可能会导致内存复制,占用内存资源;

3. 索引管理

通过readerIndex(int) 和writeIndex(int) 将索引移动到指定位置;

通过clear() 将readerIndex和writeIndex都设置为0,不会复制任何内存;

4. 查找

forEachByte();

5. 派生缓冲区

duplicate() 将会返回一个新的ByteBuf实例,修改它的内容同时也会修改对应的源实例;

copy() 可实现ByteBuf复制,获得真实副本;

四. ByteBufHolder接口

1. content() 返回这个ByteBufHolder所持有的ByteBuf;

2. copy() 深拷贝,非共享副本;

3. duplicate() 浅拷贝,共享副本;

五. ByteBuf分配

1. ByteBufAllocator接口

为了降低分配和释放内存的开销,通过ByteBufAllocator接口实现池化;

两种实现:PooledByteBufAllocator池化ByteBuf实例以提高性能并最大限度的减少内存碎片;UnpooledByteBufAllocator 不池化ByteBuf实例,每次调用时返回新的实例;

2. Unpooled缓冲区

提供静态的辅助方法创建未池化的ByteBuf实例;

同一适用于不需要Netty其他组件的非网络项目;

3. ByteBufUtil类

hexdump() 以十六进制打印ByteBuf的内容;

boolean equals(ByteBuf, ByteBuf) 判断两个ByteBuf实例的相等性;

六. 引用计数

1. 某个对象所持有的资源不再被其他对象引用时释放资源;

2. 一个ReferenceCounted实现的实例通常从1开始计数,当引用数量减少到0时,释放该实例;

3. 由最后访问引用计数对象的那一方来负责将它释放;

 

以上是关于ByteBuf的主要内容,如果未能解决你的问题,请参考以下文章