2019独角兽企业重金招聘Python工程师标准>>>

1、ByteBuf与Java NIO Buffer

ByteBuf则是Java NIO Buffer的新轮子,官方列出了一些ByteBuf的特性:

  • 需要的话,可以自定义buffer类型;
  • 通过组合buffer类型,可实现透明的zero-copy;
  • 提供动态的buffer类型,如StringBuffer一样,容量是按需扩展;
  • 无需调用flip()方法;
  • 常常「often」比ByteBuffer快。

2、ByteBuf实现类

ByteBuf提供了一些较为丰富的实现类,逻辑上主要分为两种:HeapByteBuf和DirectByteBuf,实现机制则分为两种:PooledByteBuf和UnpooledByteBuf,除了这些之外,Netty还实现了一些衍生ByteBuf(DerivedByteBuf),如:ReadOnlyByteBuf、DuplicatedByteBuf以及SlicedByteBuf。

ByteBuf实现类的类图如下:

HeapByteBuf和DirectByteBuf区别在于Buffer的管理方式:HeapByteBuf由Heap管理,Heap是Java堆的意思,内部实现直接采用byte[] array;DirectByteBuf使用是堆外内存,Direct应是采用Direct I/O之意,内部实现使用java.nio.DirectByteBuffoer。

PooledByteBuf和UnpooledByteBuf,UnpooledByteBuf实现就是普通的ByteBuf了,PooledByteBuf是4.x之后的新特性,稍后再说。

DerivedByteBuf是ByteBuf衍生类,实现采用装饰器模式对原有的ByteBuf进行了一些封装。ReadOnlyByteBuf是某个ByteBuf的只读引用;DuplicatedByteBuf是某个ByteBuf对象的引用;SlicedByteBuf是某个ByteBuf的部分内容。

SwappedByteBuf和CompositedByteBuf我觉得也算某种程度的衍生类吧,SwappedByteBuf封装了一个ByteBuf对象和ByteOrder对象,实现某个ByteBuf对象序列的逆转;CompositedByteBuf内部实现了一个ByteBuf列表,称之为组合ByteBuf,由于不懂相关的技术业务,无法理解该类的存在意义(官方解释:A user can save bulk memory copy operations using a composite buffer at the cost of relatively expensive random access.)。这两个类从逻辑上似乎完全可以继承于DerivedByteBuf,Trustin大神为啥如此设计呢?

3、简要的ByteBuf的实现机制

ByteBuf有两个指针,readerIndex和writerIndex,用以控制buffer数组的读写。读逻辑较为简单,不考虑边界的情况下,就是`return array[readerIndex++];`。这里简要分析一下HeapByteBuf的读逻辑。

1. AbstractByteBuf.ensureWritable(minWritableBytes);

2. calculateNewCapacity(writerIndex + minWritableBytes)

> 2.1 判断是否超过可写入容量 maxCapacity – writerIndex

> 2.2 超过则抛异常,否则计算新容量 writerIndex + minWritableBytes

> 2.3 判断是否超过设定阈值(4MB),超过每次增加按阈值(4MB)递增,否则

> 2.4 初始大小为64字节(newCapacity),新容量超过newCapacity则翻倍,直到newCapacity大于新容量为止

> 2.5 返回Min(newCapacity, maxCapacity);

3. UnpooledHeapByteBuf.capacity(newCapacity);

> 3.1 确保可访问,有一个`引用计数`的机制,引用计数为0,则抛异常(ensureAccessible)

> 3.2 常规操作:判断是否越界

> 3.3 如果newCapacity比原容量大,则直接创建新数组,并设置。否则

> 3.4 如果readerIndex小于新容量,将readable bytes拷贝至新的数组,反之将readerIndex和writerIndex均设置为newCapacity。

4. setByte(writerIndex++, value)

> 4.1 确保可访问

> 4.2 设置

5、ByteBuf特殊机制

5.1 Pooled

4.x开发了Pooled Buffer,实现了一个高性能的buffer池,分配策略则是结合了buddy allocation和slab allocation的jemalloc变种,代码在io.netty.buffer.PoolArena。暂未深入研读。

官方说提供了以下优势:

  • 频繁分配、释放buffer时减少了GC压力;
  • 在初始化新buffer时减少内存带宽消耗(初始化时不可避免的要给buffer数组赋初始值);
  • 及时的释放direct buffer。

当然,官方也说了不保证没有内存泄露,所以默认情况下还是采用的UnpooledByteBufAllocator。5.x还处于beta版,看它的「 new and noteworthy 」文档也没说有啥变化,哈哈哈哈,查看最新的「 new and noteworthy 」文档,PooledByteBufAllocator已经设置为默认的Allocator (revised in 2014-01-16)。

5.2 Reference Count

ByteBuf的生命周期管理引入了Reference Count的机制,感觉让我回到了CPP时代。可以通过简单的继承SimpleChannelInboundHandler实现自动释放reference count。SimpleChannelInboundHandler的事件方法如下,在消费完毕msg后,可以AutoRelease之:

 public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {boolean release = true;try {if (acceptInboundMessage(msg)) {@SuppressWarnings("unchecked")I imsg = (I) msg;messageReceived(ctx, imsg);} else {release = false;ctx.fireChannelRead(msg);}} finally {if (autoRelease && release) {ReferenceCountUtil.release(msg);}}}

这一小节可以单独拎出来和Pooled放在一起深入研读研读,有兴趣的可以先看看官方文档: Reference counted objects

5.3 Zero Copy

Zero-copy与传统意义的 zero-copy 不太一样。传统的zero-copy是IO传输过程中,数据无需中内核态到用户态、用户态到内核态的数据拷贝,减少拷贝次数。而Netty的zero-copy则是完全在用户态,或者说传输层的zero-copy机制,可以参考下图。由于协议传输过程中,通常会有拆包、合并包的过程,一般的做法就是System.arrayCopy了,但是Netty通过ByteBuf.slice以及Unpooled.wrappedBuffer等方法拆分、合并Buffer无需拷贝数据。

如何实现zero-copy的呢。slice实现就是创建一个SlicedByteBuf对象,将this对象,以及相应的数据指针传入即可,wrappedBuffer实现机制类似。

转载于:https://my.oschina.net/LucasZhu/blog/1799162

Netty 4.x – ByteBuf相关推荐

  1. netty系列之:netty中的ByteBuf详解

    文章目录 简介 ByteBuf详解 创建一个Buff 随机访问Buff 序列读写 搜索 其他衍生buffer方法 和现有JDK类型的转换 总结 简介 netty中用于进行信息承载和交流的类叫做Byte ...

  2. Netty学习之ByteBuf数据传输

    流经网络的数据总是具有相同的类型:字节.这些字节是如何流动的主要取决于我们所说的网络传输-一个帮助我们抽象底层数据传输机制的概念. netty数据传输 1.1.通过netty的异步网络处理 1.2.传 ...

  3. Netty 数据传输载体 —— ByteBuf

    在学习编解码的过程中,我们看到 Netty 大量使用了自己实现的 ByteBuf 工具类,ByteBuf 是 Netty 的数据容器,所有网络通信中字节流的传输都是通过 ByteBuf 完成的.然而 ...

  4. Netty详解ByteBuf

    目录 1 工作原理 2 基本使用 2.1 读取操作 2.2 写入操作 2.4 clear() 3 ByteBuf 使用模式 4 ByteBuf 的分配 5 ByteBuf的释放 5.1.⼿动释放 5. ...

  5. Netty ByteBuf(图解之 2)| 秒懂

    目录 Netty ByteBuf(图解二):API 图解 源码工程 写在前面 ByteBuf 的四个逻辑部分 ByteBuf 的三个指针 ByteBuf 的三组方法 ByteBuf 的引用计数 Byt ...

  6. Netty 系列三(ByteBuf).

    一.概述和原理 网络数据传输的基本单位总是字节,Netty 提供了 ByteBuf 作为它的字节容器,既解决了 JDK API 的局限性,又为网络应用程序提供了更好的 API,ByteBuf 的优点: ...

  7. 《netty实战》阅读笔记(2)——Netty 的数据容器ByteBuf

    ByteBuffer 当我们进行数据传输的时候,往往需要使用到缓冲区,常用的缓冲区就是JDK NIO类库提供的java.nio.Buffer. 实际上,7种基础类型(Boolean除外)都有自己的缓冲 ...

  8. Netty技术细节源码分析-ByteBuf的内存泄漏原因与检测

    本文的github地址:点此 该文所涉及的netty源码版本为4.1.6. Netty中的ByteBuf为什么会发生内存泄漏 在Netty中,ByetBuf并不是只采用可达性分析来对ByteBuf底层 ...

  9. Netty 的 ByteBuf 是如何支持 堆内存非池化 实现的

    Netty的ByteBuf是如何支持堆内存非池化实现的 ByteBuffer 从实现方式上分成 HeapByteBuffer 和 DirectByteBuffer 两种内存实现方式, HeapByte ...

最新文章

  1. python导入py文件-Python导入其他文件中的.py文件 即模块
  2. 深入理解Golang包导入
  3. 数据结构Java01【数据结构概述、数组基本使用】
  4. Python: pip升级报错了:You are using pip version 10.0.1, however version 20.3.3 is available.
  5. Linux: shell 中命令代换 $() 和 ``(有图有代码有真相!!!)
  6. 项目疑难杂症记录(五):fragment生命周期都回调了,却不见其页面展示
  7. 情人节海报设计没有灵感?看过来
  8. U811.1接口EAI系列之三--采购订单生成--VB语言
  9. 阿里云原生资深专家李国强:云原生上云概述
  10. mysql 5.5 字符集_mysql 5.5字符集问题
  11. K3救砖,梅林刷回官方
  12. 网易云听歌服务器异常,“网易云音乐WIFI下无法播放音乐”问题解决
  13. 使用 jsbarcode 生成条形码
  14. windows系统中如何新建桌面
  15. Seaborn 绘图中设置字体及大小
  16. 电脑清灰你要知道的那些事(二)
  17. help用法总结(基于材料:“老托福听力93篇”)
  18. CRAFT字符检测算法和SynthText合成文本数据集
  19. Unity ML-Agents 从零训练你自己的AI!:一、环境配置
  20. 个人云电脑-推荐方案 - Parsec / Fastlink

热门文章

  1. azkaban 与 java任务_azkaban任务报错java.lang.RuntimeException: The root scratch dir: /tmp/hive...
  2. 【LeetCode】整数反转
  3. 访问25%无法访问的人-如何设计可访问性
  4. 基于pnpm + lerna + typescript的最佳项目实践 - 理论篇
  5. 同时绑定onpropertychange 和 oninput 事件,实时检测 input、textarea输入改变事件,支持低版本IE,支持复制粘贴...
  6. Java学习优秀网站
  7. 第十一篇:(顺序)容器的好伴侣 --- 容器适配器
  8. Centos实现svn本地认证apache认证
  9. jQuery学习笔记2
  10. Python 2.7 Tutorial —— 流程控制