导读

原创文章,转载请注明出处。

本文源码地址:netty-source-code-analysis

本文所使用的netty版本4.1.6.Final:带注释的netty源码

本文简要地介绍ByteBuf的结构、主要api和创建方法。

1 ByteBuf的结构

每一个ByteBuf都有一个可容纳的字节上限叫capacity。在ByteBuf中通过两个指针readerIndexwriterIndex将整个个ByteBuf划分成3个部分,分别是已丢弃部分可读部分可写部分,示意图如下。

+-------------------+------------------+------------------+
|       已丢弃      |       可读       |      可写        |
|                   |     (CONTENT)    |                  |
+-------------------+------------------+------------------+
|                   |                  |                  |
0      <=      readerIndex   <=   writerIndex    <=    capacity

readerIndexwriterIndexcapacity之间满足简单地数学关系0 <= readerIndex <= writerIndex <= capcity

一个新建的从未进行过读写操作的ByteBufreaderIndexwriterIndex都为0。整个空间都是可写部分。

+---------------------------------------------------------+
|                           可写                          |
|                                                         |
+---------------------------------------------------------+
|                                                         |
0                                                      capacity
readerIndex
writerIndex

现在往其中写入一些数据,写数据的过程会引起writerIndex的移动,writerIndex移动的最大值为capacity,写数据的过程中readerIndex保持不变。

+--------------------------------------+------------------+
|                  可读                |      可写        |
|               (CONTENT)              |                  |
+--------------------------------------+------------------+
|                                      |                  |
0                   <=            writerIndex    <=    capacity
readerIndex

接着读取一些数据,读数据的过程会引起readerIndex的移动,readerIndex的最大值为writerIndex,在读数据的过程中writerIndex保持不变。已经被读取过的部分就成了已丢弃部分。

+-------------------+------------------+------------------+
|       已丢弃      |       可读       |      可写        |
|                   |     (CONTENT)    |                  |
+-------------------+------------------+------------------+
|                   |                  |                  |
0      <=      readerIndex   <=   writerIndex    <=    capacity

2 ByteBuf的主要方法

2.1 write族方法

write族方法用来向ByteBuf中写入各种类型的数据,比如writeByteswriteCharwriteInt等。另外支持写入小端字节序数据,比如writeIntLEwriteLongLE等。

write族方法的调用时写入数据的起始位置就是当前writerIndex指向的位置,写入数据会引起writerIndex的移动。

2.2 read族方法

read族方法用来从ByteBuf中读取数据,比如readByteswriteByteswriteLong等。同样也支持读取小端字节序数据,比如readIntLEreadLongLE等。

read族方法的调用会引起readerIndex的移动。

2.3 set族方法

write族方法一样,set族方法同样用来向ByteBuf中写入各种类型的数据。write能写入的数据set也能,比如writeIntsetInt。不同的是set族方法在调用时需要传递一个索引参数,也就是说需要指定写入数据的位置,比如writeInt(int value)setInt(int index, int value)

set族方法的调用不会引起writerIndex的移动。

2.4 get族方法

read族方法一样,get族方法同样用来从ByteBuf中读取数据。比如有getIntgetLong方法。与read族方法不一样的是在调用时需要传递一个索引参数,也就是说需要指定读取数据的位置,比如getInt(int index)readInt()

read族方法的调用不会引起readerIndex的移动。

2.5 读取/设置 Index的方法

ByteBuf提供了writerIndex()readerIndex()方法分别可以返回当前的writerIndexreaderIndex

除了readwrite方法可以改变readerIndexwriterIndexByteBuf也提供了可以手动设置readerIndexreaderIndex(int readerIndex)及手动设置writerIndexwriterIndex(int writerIndex)方法。

2.6 slice方法

slice方法将当前ByteBuf的可读数据区映射到一个新的ByteBuf,并返回这个新的ByteBuf。这个新的ByteBuf与原ByteBuf共享数据区域,但是拥有独立的readerIndexwriterIndex

也提供了slice(int index, int length)方法可以指定映射的数据区域范围。

对新的ByteBuf数据的修改同样会影响到的原来的ByteBuf的数据,反之亦然。

2.7 duplicate方法

duplicate方法将当前ByteBuf的整个数据区映射到一个新的ByteBuf,并返回这个新的ByteBuf。这个新的ByteBuf与原ByteBuf共享数据区域,但是拥有独立的readerIndexwriterIndex

对新的ByteBuf数据的修改同样会影响到的原来的ByteBuf的数据,反之亦然。

2.8 copy方法

copy方法返回当前ByteBuf的一个复制品,新的ByteBuf拥有与原来的ByteBuf不一样的数据区域,readerIndexwriterIndex也是独立的。

同样提供了copy(int index, int length)方法可以指定复制的数据区域范围。

对新的ByteBuf数据的修改不会影响到原来的ByteBuf,反之亦然。

2.9 retain和release方法

ByteBuf使用引用计数法来表示当前ByteBuf被引用的次数,如果一个ByteBuf的被引用次数为0,则释放该ByteBuf对应的内存。

3 ByteBuf的主要实现及创建

ByteBuf的主要实现类图如下图所示,总体上分为PooledUnPooled两类,顾名思义为池化的和非池化的,又根据分配的是直接内存还是堆内存分为HeapByteBufDirectByteBuf

3.1 通过ByteBufAllocator创建

ByteBufAllocator有两个实现分别为PooledByteBufAllocatorUnpooledByteBufAllocator对应分配出来是的PooledByteBufUnpooledByteBuf
PooledByteBufAllocator将在后续的文章中重点分析,而UnpooledByteBufAllocator则比较简单,不再赘述。

3.2 通过包裹ByteBuffer及byte[]创建

使用Unpooled.wrappedBuffer方法可以对jdkButeBufferbyte[]进行包裹创建出一个UnpooledByteBuf

4 总结

ByteBuf主要api有read/write,get/set,slice,duplicate,copy等系列方法。实现类上主要分为UnpooledPooled,并且支持分配HeapByteBufDirectByteBuf


关于作者

王建新,转转架构部服务治理负责人,主要负责服务治理、RPC框架、分布式调用跟踪、监控系统等。爱技术、爱学习,欢迎联系交流。

Netty源码深度解析-ByteBuf(1) ByteBuf简介相关推荐

  1. Netty 源码深度解析(九) - 编码

    概述 一个问题 转载于:https://juejin.im/post/5bff467fe51d4555ed5a3111

  2. Netty源码分析第5章(ByteBuf)----第5节: directArena分配缓冲区概述

    Netty源码分析第5章(ByteBuf)---->第5节: directArena分配缓冲区概述 Netty源码分析第五章: ByteBuf 第五节: directArena分配缓冲区概述 上 ...

  3. Go netpoll I/O 多路复用构建原生网络模型之源码深度解析

    原文 Go netpoll I/O 多路复用构建原生网络模型之源码深度解析 导言 Go 基于 I/O multiplexing 和 goroutine 构建了一个简洁而高性能的原生网络模型(基于 Go ...

  4. dubbo源码深度解析_Spring源码深度解析:手把手教你搭建Spring开发环境

    Spring环境搭建流程,如果是第一次接触spring源码的环境搭建,确实还是比较麻烦的. 作者使用的编译器为目前流行的lntelliJ IDEA,版本为2018旗舰版.Eclipse用户还需要自己揣 ...

  5. 《Spring源码深度解析》 PDF

    Spring源码深度解析 PDF 下载 下载地址:https://pan.baidu.com/s/1o9qEwXW 密码:vwyo 转载:http://download.csdn.net/detail ...

  6. Java LockSupport以及park、unpark方法源码深度解析

    介绍了JUC中的LockSupport阻塞工具以及park.unpark方法的底层原理,从Java层面深入至JVM层面. 文章目录 1 LockSupport的概述 2 LockSupport的特征和 ...

  7. Spring源码深度解析(郝佳)-学习-源码解析-基于注解bean定义(一)

    我们在之前的博客 Spring源码深度解析(郝佳)-学习-ASM 类字节码解析 简单的对字节码结构进行了分析,今天我们站在前面的基础上对Spring中类注解的读取,并创建BeanDefinition做 ...

  8. 《Spring源码深度解析 郝佳 第2版》AOP

    往期博客 <Spring源码深度解析 郝佳 第2版>容器的基本实现与XML文件的加载 <Spring源码深度解析 郝佳 第2版>XML标签的解析 <Spring源码深度解 ...

  9. 《Spring源码深度解析 郝佳 第2版》ApplicationContext

    往期博客: <Spring源码深度解析 郝佳 第2版>容器的基本实现与XML文件的加载 <Spring源码深度解析 郝佳 第2版>XML标签的解析 <Spring源码深度 ...

最新文章

  1. OpenGL ES 3.0 基础知识
  2. Kafka设计解析(四):Kafka Consumer解析--转
  3. [转]软件测试演义——中高级系列(序)
  4. PHP数组的访问方法有几种,数组常用方法有哪些
  5. 25. 合并两个排序的链表
  6. GHOST系统锁定主页常用软件及解决方案
  7. Spark中repartition和coalesce的区别与使用场景解析
  8. spring源码之bean加载(bean解析下篇)
  9. testng数据驱动_TestNG数据提供者
  10. Java 2 实用教程 第一章 Java入门
  11. 2022年中国研究生数学建模竞赛
  12. switchhost
  13. Matlab的卷积编码实现
  14. 关于 VB.NET 中 Obsolete 特性的问题
  15. 单片机c语言*乘法,单片机c语言教程:运算符和表达式(位运算符)
  16. AR技术应用 の 如何做一个Pokemon GO丢出精灵球抓住皮卡丘吧!(2)
  17. 生产计划管理软件功能是什么?对生产管理有何好处?
  18. 广东省如何办理甲级测绘资质
  19. 各行业分析研究报告 入口汇总
  20. 美团Java后台一面

热门文章

  1. 新手必看——Python代码运行的方法都在这里了
  2. https原理的来龙去脉
  3. feign 序列化_Spring Feign 序列化机制
  4. 如何实现集成GB28181监控平台LiveGBS的录像回放时间轴页面
  5. 统计工作总结——统计图统计表区别
  6. Praat脚本-008 | 提取某一层时长
  7. 复制(部分复制,完全复制) Mat对象
  8. OpenProcessToken LookupPrivilegeValue 和AdjustTokenPrivilege
  9. tomcat设置https端口时,8443和443的区别
  10. projectwbs表_Microsoft Project制作WBS基本使用