Netty实战-读书笔记-ByteBuf

网络数据的基本单位是字节,那么在JavaNIO和netty分别用什么作为字节容易呢?

在JavaNIO中使用ByteBuffer作为字节容器,Netty使用ByteBuf

Netty的数据处理API通过两个组件暴露出来,一个是ByteBuf,一个是ByteBufHolder

-------

跟ByteBuffer相比,ByteBuf有以下几个优点(个人觉得比较重要的几个点):

1.通过内置的复合缓冲区类型实现了透明的零拷贝

2.容量可以按需增长(类似于JDK的StringBuilder)

3.在读和写之间的切换无需像ByteBuffer一样使用flip()进行切换,而是通过维护读写索引

---------

ByteBuf是如何工作的?

从最基本的读写操作开始,ByteBuf主要维护了两个不同的索引,一个用于读取,一个用于写入

readIndex和writeIndex的起始值都为0,随着以read和write开头的方法操作后,索引随之增加,当然ByteBuf也提供了get和set的操作api,但是他们不移动索引,他们只是移动了一个相对索引。

---------

ByteBuf有多少种工作模式?

1.堆缓冲区

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

2.直接缓冲区

NIO在JDK1.4中引入了ByteBuffer类允许JVM实现通过本地调用来分配内存。这主要是为了避免在每次调用本地IO操作之前将缓冲区的内容复制到一个中间缓冲区。直接缓冲区是网络数据传输最佳的选择,因为从根本上看,堆缓冲区最后也会被JVM复制到直接缓冲区后,才通过套接字发送它们

3.复合缓冲区

复合缓冲区为多个缓冲区提供了一个聚合视图,通过一个子类CompositeByteBuf提供一个将多个缓冲区表示为单个合并缓冲区的虚拟表现

(这个复合缓冲区我不是很懂,后面我再来补,溜了。。。)

---------

字节级操作

1.ByteBuf维护了2个索引,一个readIndex一个writeIndex

2.随着读操作的进行,readIndex会随之增大,Netty提供了API可以删除掉前面已经被读取的字节,通过调用discardReadBytes()可以丢弃他们并且回收空间

3.关于discardReadBytes()有利也有弊,频繁调用discardReadBytes可以确保可写分段的最大化,但是这极有可能导致内存复制,因为可读字节必须被移动到缓冲区的开始位置。

4.同样调用clear()也可以将readIndex和writeIndex设置为0,但是它不会丢弃前面的内容。调用clear比discardReadBytes轻量得多,因为它将只是重置索引而不会复制任何的内存

---------

派生缓冲区

ByteBuf提供一些方法api来生成一个新的实例

duplicate()

slice()

slice(int,int)

Unpooled.unmodifiableBuffer()

order(ByteOrder)

readSlice(int)

这些方法都会返回一个实例,不过内容也是共享的,修改了其中的内容,源头也会被随之修改,在我看来,这和Java的浅复制概念差不多,但是如果真的需要一个现有的缓冲区的真实副本,可以使用copy()或者copy(int,int)方法,调用返回的是一个拥有独立副本数据的数据副本

---------

ByteBufHolder

Netty提供了ByteBufHolder。ByteBufHolder为Netty的高级特性提供了支持,如缓冲区池化

---------

ByteBuf的分配

为了降低分配和释放内存的开销,Netty通过ByteBufAllocator实现了池化,它可以用来分配我们所描述过的任意类型的ByteBuf的实例。它有很多API方法可以返回ByteBuf的,这里就不列出了,主要返回基于上面提到的几种类型的缓冲区的ByteBuf。还可以返回一个用于套接字的IO操作的ByteBuf

Netty提供了两种ByteBufAllocator的实现:PooledByteBufAllocator和UnpooledByteBufAllocator。前者池化了ByteBuf的实例以提高性能并能最大限度地减少内存碎片。后者实现不池化ByteBuf实例,每次调用都是返回一个新的实例。Netty默认使用了前者,当然这是可以配置的。

Netty提供了一个工具类Unpooled,它可以获取一些未被池化的基于缓冲区的ByteBuf

同样Netty也提供了一些工具类,例如ByteBufUtil,其中有一个很有用的API可以比较两个ByteBuf

Netty还引入了引用计数的概念,它可以方便我们自己手动管理内存

ByteBuf和ByteBufHolder都实现了ReferenceCounted的接口

 

 

 

 

今天就分享到这里,这些都是从《Netty实战》中提取的一些笔记,如有侵权,请联系我删除

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值