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

news2024/11/16 15:36:26

目录

  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.coloradmin.cn/o/734780.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux】第一个Linux小程序——进度条

今天为大家带来一篇关于在Linux上编写的进度条小程序的博客。 正文 我们在日常生活中使用电子产品时,经常会遇到加载的过程,这时候这些加载界面总是会附带有一些进度条,这些进度条是加载进度的可视化图形,这篇文章我们就在Linux系…

基于云原生网关的全链路灰度实践

作者: 倪海峰(海迩) 前言 随着企业规模的不断扩大,传统单体应用已很难进一步支持业务的发展,业务的迭代速度已经难以满足业务的增长,此时企业会对应用系统做微服务化的改造,降低业务的耦合度&…

keepalived脑裂

keepalived脑裂及解决方法? 一.keepalived的脑裂是如何产生的?二、HAProxy1.HAProxy概念2.HAProxy主要特性3.HAProxy负载均衡策略 4.LVS nginx HAProxy的区别5.编译部署HAProxy 一.keepalived的脑裂是如何产生的? 脑裂:指在一个高…

Elasticsearch【优化、案例】(八)-全面详解(学习总结---从入门到深化)

目录 Elasticsearch集群_测试集群状态 Elasticsearch集群_故障应对&水平扩容 Elasticsearch优化_磁盘选择 Elasticsearch优化_分片策略 Elasticsearch优化_内存设置 Elasticsearch案例_需求说明 Elasticsearch案例_ES自动补全 Elasticsearch案例_创建索引 Elastic…

多元分类预测 | Matlab 鲸鱼算法(WOA)优化xgboost的分类预测模型,多特征输入模型,WOA-xgboost分类预测

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 多元分类预测 | Matlab 鲸鱼算法(WOA)优化xgboost的分类预测模型,多特征输入模型,WOA-xgboost分类预测 多特征输入单输出的二分类及多分类模型。程序内注释详细,直接替换数据就可以用。程序语言为matlab,程序可…

MySQL查询作业

一、单表查询练习 1、查询出部门编号为30的所有员工 2、所有销售员的姓名、编号和部门编号。 3、找出奖金高于工资的员工。 4、找出奖金高于工资60%的员工。 5、找出部门编号为10中所有经理,和部门编号为20中所有销售员的详细资料。 6、找出部门编号为10中…

【三】部署zabbix-proxy代理服务器和高可用,以及监控windows系统和java应用

zabbix代理服务器和高可用 1.部署zabbix代理服务器1.1 代理端zabbix-proxy配置1.2 客户端zabbix-agent配置1.3 zabbix-proxy总结 2. 部署Zabbix高可用集群2.1 主节点zabbix-server配置2.2 备节点zabbix-server配置2.3 客户端zabbix_agent配置2.4 Zabbix高可用集群总结 3.Zabbix…

JavaScript异步编程:(回调函数、Promise、async/await、Generator)

文章目录 前言1. 回调函数1.1. 回调函数的基本概念和使用方法1.2. 回调函数的优缺点和注意事项1.3. 回调地狱和如何避免 2. Promise2.1. Promise 的基本概念和使用方法2.2. Promise 的状态和状态转换2.3. Promise 的链式调用和错误处理2.4. Promise.all 和 Promise.race 的使用…

MySQL数据库中对表进行创建,插入数据并对数据进行选择

目录 1.根据此图进行建表并插入数据 2.对表进行以下操作 a:显示所有职工的基本信息 b:查询所有职工所属部门的部门号,不显示重复的部门号 c:求出所有职工的人数 d:列出最高工和最低工资 e:列出职工的平均工资和总工资 f:创建一个只有职工号、姓名和参加工作的…

123.HTML5+CSS3完结_使用Netlify收取表单

Netlify也可以做表单接受: 我们启动一下 修改下表单 ● 接着在我们的网站输入并提交表单 ● 之后会有一个提示,提示我们提交成功 然后就能在Netlify接受到用户的表单 ● 当然这个表单只能接受100个,但是作为实验也够用了 到此&a…

文字磨练课程:提高编辑和校对效率的方法

提高编辑和校对效率,可以使你更有效地完成写作任务,提升文章质量。以下是一些方法,可以帮助你在编辑和校对过程中提高效率。 1.设定目标和计划 在开始编辑和校对前,设定明确的目标和计划。这可以帮助你集中注意力,提…

【SQL应知应会】表分区(一)• MySQL版

欢迎来到爱书不爱输的程序猿的博客, 本博客致力于知识分享,与更多的人进行学习交流 本文收录于SQL应知应会专栏,本专栏主要用于记录对于数据库的一些学习,有基础也有进阶,有MySQL也有Oracle 分区表 • MySQL版 一、分区表1.非分区表2.分区表2…

整齐有序!统一命名文件,高效管理数据轻松实现!

在数字化时代,我们每天都与大量文件打交道,文件名杂乱无章、难以辨识的情况是司空见惯的。这不仅浪费我们宝贵的时间,还可能导致信息混乱和数据丢失。但是,抛开这一切困扰吧!现在,我们向您介绍一个简单却强…

C++—string类

本期我们来学习C的string,本期内容相当的多,且有一定难度,需要大家静下心来看 目录 1.标准库中的string 1.1string类的介绍 1.2 string类的常用接口 构造函数、析构函数、赋值、拷贝构造 npos push_back append operator[ ] size …

什么是ASPICE认证

ASPICE: “AutomotiveSoftware ProcessImprovement and CapacityDetermination”,即汽车软件过程改进及能力评定。它是一个过程模型,由过程和能力度两个维度构成,用于评价汽车行业软件设计开发的能力水平。 ASPICE的6个级别&…

基于simulink进行场景变化检测(附源码)

一、前言 此示例演示如何及时分割视频。此示例中的算法可用于检测视频流中的重大变化,例如广告开始和结束的时间。场景变换在广告和营销中被广泛应用。通过改变场景,可以吸引消费者的注意力,传达产品或服务的特点和优势。例如,将…

包揽七项葵花奖 参编多项标准 萤石领跑智能家居+物联网云平台行业

7月9日,2023第七届“葵花奖”智能家居评选颁奖盛典在广交会展馆举行,萤石网络一举斩获7项重磅奖项。同时,萤石作为参编单位,受邀参与了《智能门锁测评标准》发布仪式及《智能开关测评标准》启动会,再次彰显了其在智能家…

【一些随笔】浅析 Linux和Windows:系统介绍、操作差异与使用技巧解析

一些随笔 文章内容1️⃣ 那些在Linux上顺理成章,换到Windows上就可能令人费解的事2️⃣ Linux系统介绍及使用技巧3️⃣ Windows系统介绍及使用技巧 文章内容 Linux和Windows系统的操作差异;Linux系统介绍、系统监控和优化技巧、Shell脚本编程技巧、一些…

掌握Python文件操作的绝招:打造数据之径,揭开文件操作的神秘面纱

文章目录 前言文件的基本操作打开文件操作关闭文件操作对文件进行操作1)只读文件操作read()readlines()readline()seek() 2)只写文件操作3)文件追加操作读写、追加读写操作1. r 模式打开文件2. w 模式打开文件3. a 模式打开文件 以二进制的形…

走向 Native 化:SpringDubbo AOT 技术示例与原理讲解

作者:刘军 Java 应用在云计算时代面临“冷启动”慢、内存占用高、预热时间长等问题,无法很好的适应 Serverless 等云上部署模式,GraalVM 通过静态编译、打包等技术在很大程度上解决了这些问题,同时针对 GraalVM 的一些使用限制&a…