Netty-ByteBuf简析

  Netty中ByteBuf的诞生,是因为jdk中的ByteBuffer类操作麻烦,并且存在局限性。

  jdk NIO的ByteBuffer存在一下几点问题:

  (1) ByteBuffer只维护一个标识位置的指针position,读和写都要手工维护指针位置,操作麻烦。

  (2) ByteBuffer长度固定,一旦分配完成,就不能动态扩展,操作大于 ByteBuffer的对象,容易索引越界。

  (3) ByteBuffer的API功能有限,一些高级操作需自己实现。

  

  针对以上的问题,ByteBuf的主要设计和工作原理:

  (1)底层用的还是ByteBuffer,只是在此基础上做了封装和聚合,既能公用一些基础功能,也能基于此改进和扩展。

  (2)ByteBuf维护两个位置指针,一个读,一个写,两个指针互不影响,读指针不会大于写指针。

  (3)ByteBuf的动态扩容,原理就是封装一个write方法,里面每次写入时,校验是否到达最大容量,如果是则将数据copy一个新的缓冲区。(采用倍增和步进相结合的算法)

  

  ByteBuf的一些主要功能:

  (1)基本的boolean,int,long等数据类型的读和写操作。

  (2)discard bytes操作,可以将ByteBuf重用,避免扩容导致性能耗时。

  (3)clear操作。将读指针和写指针置0,而不是清空数据。

  (4)mark和reset操作。

  (5)查找操作。如查找这个ByteBuf对象中的‘/r/n’字符。

   (6)derived bytes。

  (7)转换成标准的ByteBuffer。

  (8)随机读写操作。set和get,可以指定位置写和指定位置读,但是set不支持动态扩容。

 

  

·  ByteBuf源码分析:

  (1) ByteBuf的子类继承体系:

  

  (2)ByteBuf有两个维度的分类:

      按内存分:堆内存和直接内存。

      按是否使用内存池分:池化和非池化。

    举例:PooledHeapByteBuf,就是使用池化并且是使用堆内存的ByteBuf实例。

  

  (3)ByteBuf的内存池实现原理:

      PoolArena是一个内存池的实现类。PoolArena由多个chunk组成,而每个chunk有一个或多个page。

      chunk将多个page维护成树的结构:例如一个chunk的总大小为64,每个page的大小为4,每个节点存储的是内存地址,

       树采用深度优先遍历,但是节点选择是随机的

      结构如下图:

 

      

       

  具体详细分析,请参看该博客的分析:https://blog.csdn.net/pentiumchen/article/details/45372625

 

 

ByteBuf的相关辅助类:

  ByteBufHolder:ByteBuf的容器,是一个抽象对象,供使用者继承扩展用于不同协议。

  ByteBufAllocator:字节缓冲区分配器,可分配池化和非池化缓冲区。

  CompositeByteBuf:允许将多个ByteBuf组成一个ByteBuf,例如一个ByteBuf是消息头,一个ByteBuf是消息体,那么可以使用该类将两者组合成一个ByteBuf。

  ByteBufUtil:ByteBuf操作的工具类。

 

  

posted @ 2019-11-26 16:12  欧E  阅读(485)  评论(0编辑  收藏  举报