Linux 内核级通用内存池 —— kmalloc 体系

目录

  kmalloc 内存池中都有哪些尺寸的内存块

 kmalloc 内存池如何选取合适尺寸的内存块

 kmalloc 内存池的整体架构

KMALLOC_RECLAIM 表示需要分配可以被回收的内存,RECLAIM 类型的内存页,不能移动,但是可以直接回收,比如文件缓存页,它们就可以直接被回收掉,当再次需要的时候可以从磁盘中读取生成。或者一些生命周期比较短的内存页,比如 DMA 缓存区中的内存页也是可以被直接回收掉。​编辑  kmalloc 内存池如何进行内存的分配与回收

参考文献


kmalloc 内存池体系的底层基石是基于 slab alloactor 体系构建的,其本质其实就是各种不同尺寸的通用 slab cache。

  kmalloc 内存池中都有哪些尺寸的内存块

内核将这些不同尺寸的 slab cache 分类信息定义在 kmalloc_info[] 数组中,数组中的元素类型为 kmalloc_info_struct 结构,里边定义了对应尺寸通用内存池的相关信息。

const struct kmalloc_info_struct kmalloc_info[];/* A table of kmalloc cache names and sizes */
extern const struct kmalloc_info_struct {// slab cache 的名字const char *name;// slab cache 提供的内存块大小,单位为字节unsigned int size;
} kmalloc_info[];
  • size 用于指定该 slab cache 中所管理的通用内存块尺寸。

  • name 为该通用 slab cache 的名称,名称形式为 kmalloc-内存块尺寸(单位字节),这一点我们可以通过 cat /proc/slabinfo 命令查看。

const struct kmalloc_info_struct kmalloc_info[] __initconst = {{NULL,                      0},     {"kmalloc-96",             96},{"kmalloc-192",           192},     {"kmalloc-8",               8},{"kmalloc-16",             16},     {"kmalloc-32",             32},{"kmalloc-64",             64},     {"kmalloc-128",           128},{"kmalloc-256",           256},     {"kmalloc-512",           512},{"kmalloc-1k",           1024},     {"kmalloc-2k",           2048},{"kmalloc-4k",           4096},     {"kmalloc-8k",           8192},{"kmalloc-16k",         16384},     {"kmalloc-32k",         32768},{"kmalloc-64k",         65536},     {"kmalloc-128k",       131072},{"kmalloc-256k",       262144},     {"kmalloc-512k",       524288},{"kmalloc-1M",        1048576},     {"kmalloc-2M",        2097152},{"kmalloc-4M",        4194304},     {"kmalloc-8M",        8388608},{"kmalloc-16M",      16777216},     {"kmalloc-32M",      33554432},{"kmalloc-64M",      67108864}
};

从 kmalloc_info[]  数组中我们可以看出,kmalloc 内存池体系理论上最大可以支持 64M 尺寸大小的通用内存池。

kmalloc_info[] 数组中的 index 有一个特点,从 index = 3 开始一直到数组的最后一个 index,这其中的每一个 index 都表示其对应的 kmalloc_info[index] 指向的通用 slab cache 尺寸,也就是说 kmalloc 内存池体系中的每个通用 slab cache 中内存块的尺寸由其所在的 kmalloc_info[] 数组 index 决定,对应内存块大小为:2^index 字节,比如:

  • kmalloc_info[3] 对应的通用 slab cache 中所管理的内存块尺寸为 8 字节。但是这里的 index = 1 和 index = 2 是个例外,内核单独支持了 kmalloc-96 和 kmalloc-192 这两个通用 slab cache。它们分别管理了 96 字节大小和 192 字节大小的通用内存块。这些内存块的大小都不是 2 的次幂。

 kmalloc 内存池如何选取合适尺寸的内存块

既然 kmalloc 体系中通用内存块的尺寸分布信息可以通过一个数组 kmalloc_info[] 来定义,那么同理,最佳内存块尺寸的选取规则也可以被定义在一个数组中。

内核通过定义一个 size_index[24] 数组来存放申请内存块大小在 192 字节以下的 kmalloc 内存池选取规则。

其中 size_index[24] 数组中每个元素后面跟的注释部分为内核要申请的字节数,size_index[24] 数组中每个元素表示最佳合适尺寸的通用 slab cache 在  kmalloc_info[] 数组中的索引。

static u8 size_index[24] __ro_after_init = {3,  /* 8 */4,  /* 16 */5,  /* 24 */5,  /* 32 */6,  /* 40 */6,  /* 48 */6,  /* 56 */6,  /* 64 */1,  /* 72 */1,  /* 80 */1,  /* 88 */1,  /* 96 */7,  /* 104 */7,  /* 112 */7,  /* 120 */7,  /* 128 */2,  /* 136 */2,  /* 144 */2,  /* 152 */2,  /* 160 */2,  /* 168 */2,  /* 176 */2,  /* 184 */2   /* 192 */
};

size_index 数组只是定义申请内存块在 192 字节以下的 kmalloc 内存池选取规则,当申请内存块的尺寸超过 192 字节时,内核会通过 fls 函数来计算 kmalloc_info 数组中的通用 slab cache 索引。

 kmalloc 内存池的整体架构

kmalloc 内存池的本质其实还是 slab 内存池,底层依赖于 slab alloactor 体系,在 kmalloc 体系的内部,管理了多个不同尺寸的 slab cache,kmalloc 只不过负责根据内核申请的内存块尺寸大小来选取一个最佳合适尺寸的 slab cache

  kmalloc 内存池中的内存来自于上面的 ZONE_DMA 和 ZONE_NORMAL 物理内存区域,也就是内核虚拟内存空间中的直接映射区域。

  • KMALLOC_NORMAL 表示 kmalloc 需要从 ZONE_NORMAL 物理内存区域中分配内存。

  • KMALLOC_DMA 表示 kmalloc 需要从 ZONE_DMA 物理内存区域中分配内存。

  • KMALLOC_RECLAIM 表示需要分配可以被回收的内存,RECLAIM 类型的内存页,不能移动,但是可以直接回收,比如文件缓存页,它们就可以直接被回收掉,当再次需要的时候可以从磁盘中读取生成。或者一些生命周期比较短的内存页,比如 DMA 缓存区中的内存页也是可以被直接回收掉。  kmalloc 内存池如何进行内存的分配与回收

参考文献

深度解读 Linux 内核级通用内存池 —— kmalloc 体系

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/14735.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[NSSRound#13 Basic]flask?jwt?解题思路过程

过程 打开题目链接,是一个登录框,不加验证码,且在注册用户名admin时提示该用户名已被注册,因此爆破也是一种思路。不过根据题目名字中的提示,jwt,且拥有注册入口,注册一个用户先。 注册完用户…

8、动手学深度学习——现代卷积神经网络:AlexNet

1、学习表征 在2012年前,图像特征都是机械地计算出来的。事实上,设计一套新的特征函数、改进结果,并撰写论文是盛极一时的潮流 另一组研究人员,包括Yann LeCun、Geoff Hinton、Yoshua Bengio、Andrew Ng、Shun ichi Amari和Juer…

测试编排必要性

目录 前言: 测试编排定义 测试编排和自动化 测试编排的好处 自动化的测试编排策略 自动化/编排工具 测试编排和CI/CD 学点啥 前言: 编排是一种组织和安排信息的过程,它在各种情境中都是非常重要的。在撰写文章、演讲或其他形式的表达…

【真题解析】系统集成项目管理工程师 2022 年上半年真题卷(综合知识)

本文为系统集成项目管理工程师考试(软考) 2022 年上半年真题(全国卷),包含答案与详细解析。考试共分为两科,成绩均 ≥45 即可通过考试: 综合知识(选择题 75 道,75分)案例分析&#x…

【Elasticsearch】索引库操作

目录 2.索引库操作 2.1.mapping映射属性 2.2.索引库的CRUD 2.2.1.创建索引库和映射 基本语法: 示例: 2.2.2.查询索引库 2.2.3.修改索引库 2.2.4.删除索引库 2.2.5.总结 2.索引库操作 索引库就类似数据库表,mapping映射就类似表的…

软件设计模式与体系结构-软件体系-层次软件体系结构

目录 四、层次软件体系结构简介代码两种方式的区别双向分层分层风格 VS 主程序-子过程风格:二者的不同层次软件体系结构的优点层次软件体系结构的缺点 课程作业 四、层次软件体系结构 层次之间存在接口,通过接口形成call/return的关系,上层是…

深度神经网络量化算法基础理论

关于量化,之前的博客中首先从第一个将量化思想应用在神经网络模型上的工作开始介绍,随后阐述了量化领域的极端情况,即二值化与三值化,并指出尽管目前已经存在多种对二值网络的优化方法,但是显然因极端量化带来的严重精…

优化软件测试成本,7个步骤简单执行~

软件测试可以防止那些修复起来成本很高的错误,从而避免将来因为它们所导致的高昂费用。以下是优化前期成本的7个步骤。 为什么软件测试很重要? 平均一款手机应用程序包含大约5万行代码,微软Windows操作系统有大约5000万行代码,而…

【技能实训】DMS数据挖掘项目-Day02

文章目录 任务3【任务3.1】实现日志实体类【任务3.2】创建日志业务类,实现日志信息的采集及打印输出【任务3.3】创建日志测试类,测试任务3.2中的程序,演示日志信息的采集及打印输出 任务4【任务4.1】物流实体信息类【任务4.2】创建物流业务类…

Python一行命令搭建HTTP服务器并外网访问+-+内网穿透

文章目录 1.前言2.本地http服务器搭建2.1.Python的安装和设置2.2.Python服务器设置和测试 3.cpolar的安装和注册3.1 Cpolar云端设置3.2 Cpolar本地设置 4.公网访问测试5.结语 转载自远程内网穿透的文章:【Python】快速简单搭建HTTP服务器并公网访问「cpolar内网穿透…

SQL高级教程

SQL TOP 子句 TOP 子句 TOP 子句用于规定要返回的记录的数目。 对于拥有数千条记录的大型表来说,TOP 子句是非常有用的。 注释:并非所有的数据库系统都支持 TOP 子句。 SQL Server 的语法: SELECT TOP number|percent column_name(s) F…

JMeter元件

【测试计划–线程组/Threads(Users)】 模拟大量用户负载的情况,线程组可以设置运行的线程数(多少线程就代表多少用户); 【测试计划–线程组–取样器/sampler】 用来模拟用户操作,向服务器发出http请求、Webservice请求、java请求等&#xf…