netty in action 笔记 二

 

 

 

netty的数据容器

    网络数据的基本单位大多为字节,Java NIO 提供了ByteBuffer 作为它的字节容器,但使用起来过于复杂和繁琐。在Netty中, ByteBuffer 替代品是ByteBuf,一个强大的实现,既解决了JDK API 的局限性,又为网络应用程序的开发者提供了更好的API。由不同的索引分别控制读访问和写访问的字节数组。

ByteBuf

    Netty 的数据处理API 通过两个组件暴露给用户,它们是 abstract class ByteBuf 和interface ByteBufHolder。

    下面是一些ByteBuf API 的优点:

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

  7. 支持引用计数;

  8. 支持池化。

ByteBuf 的使用模式

  堆缓冲区:将数据存储在JVM 的堆空间中,使用数组实现

      堆缓冲的优点是:由于数据存储在JVM的堆中可以快速创建和快速释放,并且提供了数组的直接快速访问的方法。

      堆缓冲缺点是:每次读写数据都要先将数据拷贝到直接缓冲区再进行传递。

      直接缓冲区:NIO 在JDK 1.4 中引入的ByteBuffer 类允许JVM 实现通过本地调用来分配内存。

                           这主要是为了避免在每次调用本地I/O 操作之前(或者之后)将缓冲区的内容复制到一个中间缓冲区(或者从中间缓冲区把内容复制到缓冲区)。ByteBuffer的                             Javadoc明确指出:“直接缓冲区的内容将驻留在常规的会被垃圾回收的堆之外。直接缓冲区的主要缺点是,相对于基于堆的缓冲区,它们的分配和释放都较为                               昂贵。在处理遗留代码时,因为数据不在堆上,所以需要将数据全部复制

                         

 

    复合缓冲区:复合缓冲区就类似于一个ByteBuf的组合视图,在这个视图里面我们可以创建不同的ByteBuf(可以是不同类型的)。 这样,复合缓冲区就类似于一个列表,我们可以动态的往里面添加和删除其中的ByteBuf。

          

 

 ByteBufHolder接口:存储ByteBfu的各种属性值

ByteBuf的分配:

    按需分配:ByteBufAllocator 接口

    

  可以通过Channel(每个都可以有一个不同的ByteBufAllocator 实例)或者绑定到ChannelHandler 的ChannelHandlerContext 获取一个到ByteBufAllocator 的引用。

    

Netty提供了两种ByteBufAllocator的实现:PooledByteBufAllocator和Unpooled-ByteBufAllocator。前者池化了ByteBuf的实例以提高性能并最大限度地减少内存碎片。此实

现使用了一种称为jemalloc的已被大量现代操作系统所采用的高效方法来分配内存。后者的实现不池化ByteBuf实例,并且在每次它被调用时都会返回一个新的实例。

  虽然Netty默认使用了PooledByteBufAllocator,但这可以很容易地通过Channel-Config API或者在应用程序中指定一个不同的分配器来更改。

 Unpooled 缓冲区:   

  它提供了静态的辅助方法来创建未池化的ByteBuf实例。

  

ByteBufUtil 类:  

  ByteBufUtil 提供了用于操作ByteBuf 的静态的辅助方法。因为这个API 是通用的,并且和池化无关,所以这些方法已然在分配类的外部实现。

引用计数:当指向某个对象的引用数目为0时,该对象所占资源将被回收。

  引用计数对于池化实现(如PooledByteBufAllocator)来说是至关重要的,它降低了内存分配的开销。

要点:

  1. 使用不同的读索引和写索引来控制数据访问;

  2. 使用内存的不同方式——基于字节数组和直接缓冲区;

  3. 通过CompositeByteBuf 生成多个ByteBuf 的聚合视图;

  4. 数据访问方法——搜索、切片以及复制;

  5. 读、写、获取和设置API;

  6. ByteBufAllocator 池化和引用计数。

 

posted on 2018-06-14 17:49  爱养花的码农  阅读(156)  评论(0编辑  收藏  举报