Netty ByteBuf梳理
我们知道,网络数据的基本单位总是字节。Java NIO提供了ByteBuffer作为它的字节容器,但是这个类使用起来过于复杂,而且也有些繁琐。
Netty的ByteBuffer替代品是ByteBuf,一个强大的实现,既解决了JDK API的局限性,又为网络应用程序的开发者提供了更好的API。
ByteBuf的API
Netty的数据处理API通过两个组件暴露——abstract class ByteBuf和interface ByteBufHolder。
下面是一些ByteBuf API的优点:
- 它可以被用户自定义的缓冲区类型扩展;
- 通过内置的复合缓冲区类型实现了透明的零拷贝;
- 容量可以按需增长(类似于JDK的StringBuilder);
- 在读和写这两种模式之间切换不需要调用ByteBuffer的flip()方法;
- 读和写使用了不同的索引;
- 支持方法的链式调用;
- 支持引用计数;
- 支持池化。
其他可以用于管理ByteBuffer实例的分配,以及执行各种针对于数据容器本身和它所持有的数据的操作。
因为所有的网络通信都涉及字节序列的移动,所以高效易用的数据结构明显是必不可少的。Nety的ByteBuf实现满足并超越了这些需求。
ByteBuf维护了两个不同的索引:一个用于读取,一个用于写入。当你从ByteBuf读取时,它的readIndex将会被递增已经被读取的字节数。同样的,当你写入ByteBuf时,它的writeIndex也会被递增。
要了解这些索引两两之间的关系,如果打算读取字节直到radIndex达到writeIndex同样的值,你将会到达“可以读取的”数据的末尾。如果试图读取超过改点的数据将会触发一个IndexOutOfBoundsException。
名称为read或者write开头的ByteBuf方法,将会推进其对应的索引,而名称以ste或get开头的操作则不会。后面的这些方法将在作为一个参数传入的一个相对索引上执行操作。
ByteBufHolder接口
我们经常发现,除了实际的数据负载之外,我们还需要存储各种属性值。HTTP响应便是一个很好的例子,除了表示为字节的内容,还包括状态码、cookie等。
为了处理这种常见的用例,Netty提供了ByteBufHolder。ByteBufHolder也为Netty的高级特性提供了支持,入缓冲区池化,其中可以从池中借用ByteBuf,并且在需要时自动释放。
ByteBufHolder只有几种用于访问底层数据和引用计数的方法。
| 名称 | 描述 |
|---|---|
| content() | 返回由这个ByteBufHolder所持有的ByteBuf |
| copy() | 返回这个ByteBufHolder得一个深拷贝,包括一个其所包含的ByteBuf的非共享拷贝 |
| duplicate() | 返回这个ByteBufHolder的以个浅拷贝,包括一个其所包含的ByteBuf的共享拷贝 |
如果想要实现一个将其有效负载存储在ByteBuf中的消息对象,那么ByteBufHolder将是个不错的选择。
ByteBuf分配
- 按需分配:ByteBufAllocator接口
为了降低分配和释放内存的开销,Netty通过interface ByteBufAllocator实现了(ByteBuf的)池化,它可以用来分配我们所描述过的任意类型的ByteBuf实例。使用池化是应用程序的决定,其并不会以任何方式改变ByteBuf API(的语义)。
可以通过Channel(每一个可以有一个不同的ByteBufAllocator的实例)或者绑定到ChannelHandler的ChannelHnadlerContext获取一个到ByteBufAlocator的引用。
Channel channel = ... ;
ByteBufAllocator allocator = channel.alloc();
...
ChannelHandlerContext ctx = ... ;
ByteBufAllocator allocator2 = ctx.alloc();
...
- Unpooled缓冲区
可能某些情况下,你未能获取一个到ByteBufAllocator的引用。对于这种情况,Netty提供了一个简单地称为Unpooled的工具类,它提供了静态的辅助方法来创建未池化的ByteBuf实例。
Netty ByteBuf梳理的更多相关文章
- 对于 Netty ByteBuf 的零拷贝(Zero Copy) 的理解
此文章已同步发布在我的 segmentfault 专栏. 根据 Wiki 对 Zero-copy 的定义: "Zero-copy" describes computer opera ...
- Netty ByteBuf(图解之 2)| 秒懂
目录 Netty ByteBuf(图解二):API 图解 源码工程 写在前面 ByteBuf 的四个逻辑部分 ByteBuf 的三个指针 ByteBuf 的三组方法 ByteBuf 的引用计数 Byt ...
- netty byteBuf (二)
netty重新定义了byteBuf 而没使用jdk byteBuffer netty byteBuf与jdk byteBuffer的区别 (1)jdk buffer长度固定 byteBuf超过最大 ...
- Netty ByteBuf源码分析
Netty的ByteBuf是JDK中ByteBuffer的升级版,提供了NIO buffer和byte数组的抽象视图. ByteBuf的主要类集成关系: (图片来自Netty权威指南,图中有一个画错的 ...
- Netty ByteBuf 和 String 转换
参考https://blog.csdn.net/o1101574955/article/details/81024102 参考http://youyu4.iteye.com/blog/2361959 ...
- Netty ByteBuf和Nio ByteBuffer
参考https://blog.csdn.net/jeffleo/article/details/69230112 一.简介 Netty中引入了ByteBuf,它相对于ByteBuffer来说,带来了很 ...
- Netty ByteBuf泄露定位修改。
1. ByteBuf 2. 问题描述 日志记录中报堆外内存溢出. 3. 问题定位及修改 Netty提供了ByteBuf泄露的检测机制. JVM启动参数中添加: -Dio.netty.leakDetec ...
- 手写MQ框架(四)-使用netty改造梳理
一.背景 书接上文手写MQ框架(三)-客户端实现,前面通过web的形式实现了mq的服务端和客户端,现在计划使用netty来改造一下.前段时间学习了一下netty的使用(https://www.w3cs ...
- netty ByteBuf分析
1.Heap Buffer(堆缓冲区) 2.Direct Buffer(直接缓冲区) 3.Composite Buffer(复合缓冲区) 4.PooledByteBuf 池缓冲 readerInex ...
随机推荐
- Linux环境JDK安装
Java的编程离不开jdk,今天本文主要讲下Linux下的JDK安装与配置 1.卸载Linux自带的JDK #检测jdk安装包 [root@localhost ~]# rpm -qa | grep j ...
- sublime text3怎么批量查找替换文件夹中的字符
在编写代码的时候,往往有些代码是重复的,但是如果要改一处代码,其他的地方也要改.那么怎么批量修改呢?下面小编就以sublime text3为例来讲解一下sublime text3怎么批量查找替换文件夹 ...
- Struts2 05---拦截器
一.Struts2拦截器原理: Struts2拦截器的实现原理相对简单,使用了aop思想和责任链模式,当请求struts2的action时,Struts 2会查找配置文件,并根据其配置实例化相对的拦截 ...
- PHPCMS模板里面使用自定义函数
首先我在/phpcms/libs/functions/extention.func.php里面新增了一个函数 ============================================= ...
- HTML面试
------------------------------------------------------- 行列 td tr ol -------------------------------- ...
- ngRx 官方示例分析 - 6 - Effect
@ngrx/effect 前面我们提到,在 Book 的 reducer 中,并没有 Search 这个 Action 的处理,由于它需要发出一个异步的请求,等到请求返回前端,我们需要根据返回的结果来 ...
- Linuxc - 通过管道,让小程序更有活力
通过管道,让小程序更有活力 root@jiqing:~/cspace/les6# ls avg.c avg.out input.c input.out 一个负责输入,一个负责统计平均值 avg.c # ...
- Nginx日志中的金矿 -- 好文收藏
转:http://www.infoq.com/cn/articles/nignx-log-goldmine Nginx(读作Engine-X)是现在最流行的负载均衡和反向代理服务器之一.如果你是一名中 ...
- Switch-case 内定义变量的问题
Switch-case 内定义变量的问题 这个问题需要分开讨论,C 语言和 C++ 的标准定义是不同的. C++ int Caset(int a) { switch (a) { case 1: int ...
- java里程碑之泛型--类型通配符
1,泛型与数组在子类上面的对比 在整理java泛型的类型通配符之前,我们先来研究下java在数组设计上的一个不合理.我们来看下面代码: public class Test { public stati ...