聊完了结构和使用模式,再来看看 ByteBuf 是如何分配缓冲区的数据的 。
Netty 提供了两种 ByteBufAllocator 的实现,他们分别是:
- PooledByteBufAllocator,实现了 ByteBuf 的对象的池化,提高性能减少内存碎片 。
- Unpooled-ByteBufAllocator,没有实现对象的池化,每次会生成新的对象实例 。
对象的生成和销毁,会大量地调用 allocate 和 release 方法,因此内存池面临碎片空间回收的问题,在频繁申请和释放空间后,内存池需要保证连续的内存空间,用于对象的分配 。
基于这个需求,有两种算法用于优化这一块的内存分配:伙伴系统和 slab 系统 。
伙伴系统,用完全二叉树管理内存区域,左右节点互为伙伴,每个节点代表一个内存块 。内存分配将大块内存不断二分,直到找到满足所需的最小内存分片 。
内存释放会判断释放内存分片的伙伴(左右节点)是否空闲,如果空闲则将左右节点合成更大块内存 。
slab 系统,主要解决内存碎片问题,将大块内存按照一定内存大小进行等分,形成相等大小的内存片构成的内存集 。
按照内存申请空间的大小,申请尽量小块内存或者其整数倍的内存,释放内存时,也是将内存分片归还给内存集 。
Netty 内存池管理以 Allocate 对象的形式出现 。一个 Allocate 对象由多个 Arena 组成,每个 Arena 能执行内存块的分配和回收 。
Arena 内有三类内存块管理单元:
- TinySubPage
- SmallSubPage
- ChunkList
当用户申请内存介于 tinySize 和 smallSize 之间时,从 tinySubPage 中获取内存块 。
申请内存介于 smallSize 和 pageSize 之间时,从 smallSubPage 中获取内存块;介于 pageSize 和 chunkSize 之间时,从 ChunkList 中获取内存;大于 ChunkSize(不知道分配内存的大小)的内存块不通过池化分配 。
Netty 的 Bootstrap说完了 Netty 的核心组件以及数据存储 。再回到最开始的例子程序,在程序最开始的时候会 new 一个 Bootstrap 对象,后面所有的配置都是基于这个对象展开的 。

文章插图
生成 Bootstrap 对象
Bootstrap 的作用就是将 Netty 核心组件配置到程序中,并且让他们运行起来 。
从 Bootstrap 的继承结构来看,分为两类分别是 Bootstrap 和 ServerBootstrap,一个对应客户端的引导,另一个对应服务端的引导 。

文章插图
支持客户端和服务端的程序引导
客户端引导 Bootstrap,主要有两个方法 bind() 和 connect() 。Bootstrap 通过 bind() 方法创建一个 Channel 。
在 bind() 之后,通过调用 connect() 方法来创建 Channel 连接 。

文章插图
Bootstrap 通过 bind 和 connect 方法创建连接
服务端引导 ServerBootstrap,与客户端不同的是在 Bind() 方法之后会创建一个 ServerChannel,它不仅会创建新的 Channel 还会管理已经存在的 Channel 。

文章插图
ServerBootstrap 通过 bind 方法创建/管理连接
通过上面的描述,服务端和客户端的引导存在两个区别:
- ServerBootstrap(服务端引导)绑定一个端口,用来监听客户端的连接请求 。而 Bootstrap(客户端引导)只要知道服务端 IP 和 Port 建立连接就可以了 。
- Bootstrap(客户端引导)需要一个 EventLoopGroup,但是 ServerBootstrap(服务端引导)则需要两个 EventLoopGroup 。因为服务器需要两组不同的 Channel 。第一组 ServerChannel 自身监听本地端口的套接字 。第二组用来监听客户端请求的套接字 。

文章插图
ServerBootstrap 有两组 EventLoopGroup
总结我们从 NIO 入手,谈到了 Selector 的核心机制 。然后通过介绍 Netty 客户端和服务端源代码运行流程,让大家对 Netty 编写代码有基本的认识 。
推荐阅读
- 学会使用 Spring Boot 的异步调用
- 脂肪通过什么排出?
- 用Apple Configurator 2从iOS复制软件
- 健康生活,从一杯清茶开始……
- 送茶叶代表什么意思?
- 程序安装包咋制作的?Qt程序打包三部曲,从应用程序到安装包
- 很多人学Spring框架,总觉得IOC模糊不清?
- 一个人如何开发一款app?
- 我的第一次安卓app开发经历
- 用python处理excel文件有多轻松?工作从未如此简单
