Netty ByteBuf

ByteBuf的工作原理

ByteBuf依然是个Byte数组的缓冲区,它的基本功能应该与JDK的ByteBuffer 一致

ByteBuf通过两个位置指针来协助缓冲区的读写操作,读操作使用readerIndex,写操作使用writerIndex

readerInder 和writerIndex 的取值一开始都是0,随着数据的写入writerIndex 会增加,读取数据会使readerIndex增加,

由于写操作不修改readerIndex 指针,读操作不修改writerIndex指针,因此读写之间不再需要调整位置指针,这极大地简化了缓冲区的读写,避免了由于遗漏或者不熟悉flip()操作导致的功能异常。

ByteBuf是一个抽象类,内部全部是抽象的函数接口,AbstractByteBuf这个抽象类基本实现了ByteBuf,下面我们通过分析AbstractByteBuf里面的实现来分析ByteBuf的工作原理。

ByteBuf都是基于字节序列的,类似于一个字节数组。在AbstractByteBuf里面定义了下面5个变量:

 

ByteBuf的优点: 
(1)ByteBuf是吸取ByteBuffer的缺点之后重新设计,存储字节的数组是动态的,最大是Integer.MAX_VALUE。这里的动态性存在write操作中,write时得知buffer不够时,会自动扩容。

(2) ByteBuf的读写索引分离,使用起来十分方便。此外ByteBuf还新增了很多方便实用的功能。

下面是一些 ByteBuf API 的优点:

  •  它可以被用户自定义的缓冲区类型扩展;
  •  通过内置的复合缓冲区类型实现了透明的零拷贝;
  •  容量可以按需增长(类似于 JDK 的 StringBuilder);
  •  在读和写这两种模式之间切换不需要调用 ByteBuffer 的 flip()方法;
  •  读和写使用了不同的索引;
  •  支持方法的链式调用;
  • 支持引用计数;
  • 支持池化。

ByteBuf 与JDK中的 ByteBuffer 的最大区别之一就是: 
(1)netty的ByteBuf采用了读/写索引分离,一个初始化的ByteBuf的readerIndex和writerIndex都处于0位置。 
(2)当读索引和写索引处于同一位置时,如果我们继续读取,就会抛出异常IndexOutOfBoundsException。 
(3)对于ByteBuf的任何读写操作都会分别单独的维护读索引和写索引。maxCapacity最大容量默认的限制就是Integer.MAX_VALUE。

注意:使用完ByteBuf之后,一定要release,否则会造成内存泄漏。区分ByteBuf底层是heap buffer还是direct buffer,可以根据ByteBuf.hasArray()来判断,因为heap buffer返回true(heap上的ByteBuffy底层实现就是byte[] 数组),direct buffer返回false。

posted on 2020-10-27 17:38  shumeigang  阅读(127)  评论(0)    收藏  举报

导航