Netty 作为一款高性能的 RPC 框架必然涉及到频繁的内存分配销毁操作 。
文章插图
图片来自 Pexels
如果是在堆上分配内存空间将会触发频繁的 GC,JDK 在 1.4 之后提供的 NIO 也已经提供了直接直接分配堆外内存空间的能力,但是也仅仅是提供了基本的能力,创建、回收相关的功能和效率都很简陋 。
基于此,在堆外内存使用方面,Netty 自己实现了一套创建、回收堆外内存池的相关功能 。基于此我们一起来看一下 Netty 是如何实现内存分配的 。
Netty 中的数据容器分类
谈到数据保存肯定要说到内存分配,按照存储空间来划分,可以分为堆内存和堆外内存;按照内存区域连贯性来划分可以分为池化内存和非池化内存 。这些划分在 Netty 中的实现接口分别如下 。
按照底层存储空间划分:
- 堆缓冲区:HeapBuffer
- 直接缓冲区:DirectBuffer
- 池化:PooledBuffer
- 非池化:UnPooledBuffer
什么是池化?
一般申请内存是检查当前内存哪里有适合当前数据块大小的空闲内存块,如果有就将数据保存在当前内存块中 。
那么池化想做的事情是:既然每次来数据都要去找内存地址来存,我就先申请一块内存地址,这一块就是我的专用空间,内存分配、回收我全权管理 。
池化解决的问题:内存碎片 。
内碎片:就是申请的地址空间大于真正数据使用的内存空间 。
比如固定申请 1M 的空间作为某个线程的使用内存,但是该线程每次最多只占用 0.5M,那么每次都有 0.5M 的碎片 。如果该空间不被有效回收时间一长必然存在内存空洞 。
外碎片:是指多个内存空间合并的时候发现不够分配给待使用的空间大小 。
比如有一个 20byte,13byte 的连续内存空间可以被回收,现在有一个 48byte 的数据块需要存储,而这两个加起来也只有 33byte 的空间,必然不会被使用到 。
如何实现内存池?
①链表维护空闲内存地址
最简单的就是弄一个链表来维护当前空闲的内存空间地址 。如果有使用就从链表删除,有释放就加入链表对应位置 。
这种方式实现简单,但是搜索和释放内存维护的难度还是比较大,不太适合 。
②定长内存空间分配
维护两个列表,一个是未分配内存列表,一个是已分配内存列表 。每个内存块都是一样大小,分配时如果不够就将多个块合并到一起 。
这种方式的缺点就是会浪费一定的内存空间,如果有特定的场景还是没有问题 。
③多段定长池分配
在上面的定长分配基础上,由原来的固定一个长度分配空间变为按照不同对象大小(8,16,32,64,128,256,512,1k…64K),的方式分配多个固定大小的内存池 。
每次要申请内存的时候按照当前对象大小去对应的池中查找是否有剩余空间 。
linux 本身支持动态内存分配和释放,对应的命令为:malloc/free 。malloc 的全称是 memory allocation,中文叫动态内存分配,用于申请一块连续的指定大小的内存块区域以 void* 类型返回分配的内存区域地址 。
malloc/free 的实现过程:
- 空闲存储空间以空闲链表的方式组织(地址递增),每个块包含一个长度、一个指向下一块的指针以及一个指向自身存储空间的指针 。(因为程序中的某些地方可能不通过 malloc 调用申请,因此 malloc 管理的空间不一定连续)
- 当有申请请求时,malloc 会扫描空闲链表,直到找到一个足够大的块为止 。(首次适应)(因此每次调用 malloc 时并不是花费了完全相同的时间)
- 如果该块恰好与请求的大小相符,则将其从链表中移走并返回给用户 。如果该块太大,则将其分为两部分,尾部的部分分给用户,剩下的部分留在空闲链表中(更改头部信息) 。因此 malloc 分配的是一块连续的内存 。
- 释放时首先搜索空闲链表,找到可以插入被释放块的合适位置 。如果与被释放块相邻的任一边是一个空闲块,则将这两个块合为一个更大的块,以减少内存碎片 。
Netty 采用了 jemalloc 的思想,这是 FreeBSD 实现的一种并发 malloc 的算法 。
jemalloc 依赖多个 Arena(分配器)来分配内存,运行中的应用都有固定数量的多个 Arena,默认的数量与处理器的个数有关 。
推荐阅读
- 大学|高中生为什么要拼尽全力考入名校?这是我见到最好的答案
- 解冻淘宝店铺保证金需要把店铺商品下架吗 淘宝店被彻底释放了保证金怎么办?
- 生意参谋页面很多我想最快了解某一个指标 生意参谋商城点击占比在哪里
- 淘宝网店运营方案 淘宝运营方案策划
- 手机如何找回原来开的淘宝店铺 淘宝店铺被彻底释放后信誉还有吗
- 淘宝店铺推广方式 如何做淘宝推广
- 淘宝生意参谋怎么看同行转化率 阿里巴巴生意参谋怎么看同行数据
- 呈贡蒲门茶品鉴地,我们持盅看茶
- 怎么弄封别人的淘宝店 淘宝店铺被彻底释放了怎么办
- 淘宝卖家中心的体检中心在哪里 淘宝的体检中心在哪