一文讲解Linux内核内存管理架构

内存管理子系统可能是linux内核中最为复杂的一个子系统,其支持的功能需求众多,如页面映射、页面分配、页面回收、页面交换、冷热页面、紧急页面、页面碎片管理、页面缓存、页面统计等,而且对性能也有很高的要求。本文从内存管理硬件架构、地址空间划分和内存管理软件架构三个方面入手,尝试对内存管理的软硬件架构做一些宏观上的分析总结。

内存管理硬件架构

因为内存管理是内核最为核心的一个功能,针对内存管理性能优化,除了软件优化,硬件架构也做了很多的优化设计。下图是一个目前主流处理器上的存储器层次结构设计方案。

从图中可以看出,对于逻辑cache架构读写内存,硬件设计了3条优化路径。

1)首先L1 cache支持虚拟地址寻址,保证CPU出来的虚拟地址(VA)不需要转换成物理地址(PA)就可以用来直接查找L1 cache,提高cache查找效率。当然用VA查找cache,有安全等缺陷,这需要CPU做一些特别的设计来进行弥补,具体可以阅读《计算机体系结构:量化研究方法》了解相关细节。

2)如果L1 cache没有命中,这就需要进行地址转换,把VA转换成PA。linux的内存映射管理是通过页表来实现的,但是页表是放在内存中的,如果每次地址转换过程都需要访问一次内存,其效率是十分低下的。这里CPU通过TLB硬件单元(在MMU中)来加速地址转换。

3)获得PA后,在L2 cache中再查找缓存数据。L2 cache一般比L1 cache大一个数量级,其查找命中率也更高。如果命中获得数据,则可避免去访问内存,提高访问效率。

可见,为了优化内存访问效率,现代处理器引入多级cache、TLB等硬件模块。

内存映射空间划分

根据不同的内存使用方式和使用场景需要,内核把内存映射地址空间划分成多个部分,每个划分空间都有自己的起止地址、分配接口和使用场景。下图是一个常见的32位地址空间划分结构。

  • DMA内存动态分配地址空间:
    一些DMA设备因为其自身寻址能力的限制,不能访问所有内存空间。如早期的ISA设备只能在24位地址空间执行DMA,即只能访问前16MB内存。所以需要划分出DMA内存动态分配空间,即DMA zone。其分配通过加上GFP_ATOMIC控制符的kmalloc接口来申请。
  • 直接内存动态分配地址空间
    因为访问效率等原因,内核对内存采用简单的线性映射,但是因为32位CPU的寻址能力(4G大小)和内核地址空间起始的设置(3G开始),会导致内核的地址空间资源不足,当内存大于1GB时,就无法直接映射所有内存。无法直接映射的地址空间部分,即highmem zone。在DMA zone和highmem zone中间的区域即normal zone,主要用于内核的动态内存分配。其分配通过kmalloc接口来申请。
  • 高端内存动态分配地址空间:
    高端内存分配的内存是虚拟地址连续而物理地址不连续的内存,一般用于内 核动态加载的模块和驱动,因为内核可能运行了很久,内存页面碎片情况严 重,如果要申请大的连续地址的内存页会比较困难,容易导致分配失败。根 据应用需要,高端内存分配提供多个接口:

vmalloc:指定分配大小,page位置和虚拟地址隐式分配;

vmap:指定page位置数组,虚拟地址隐式分配;

ioremap:指定物理地址和大小,虚拟地址隐式分配。

  • 持久映射地址空间
    内核上下文切换会伴随着TLB刷新,这会导致性能下降。但一些使用高端内存的模块对性能也有很高要求。持久映射空间在内核上下文切换时,其TLB不刷新,所以它们映射的高端地址空间寻址效率较高。其分配通过kmap接口来申请。kmap与vmap的区别是:vmap可以映射一组page,即page不连续,但虚拟地址连续,而kmap只能映射一个page到虚拟地址空间。kmap主要用于fs、net等对高端内存访问有较高性能要求的模块中。
  • 固定映射地址空间:
    持久映射的问题是可能会休眠,在中断上下文、自旋锁临界区等不能阻塞的场景中不可用。为了解决这个问题,内核又划分出固定映射,其接口不会休眠。固定映射空间通过kmap_atomic接口来映射。kmap_atomic的使用场景与kmap较为相似,主要用于mm、fs、net等对高端内存访问有较高性能要求而且不能休眠的模块中。

不同的CPU体系架构在地址空间划分上不尽相同,但为了保证CPU体系差异对外部模块不可见,内存地址空间的分配接口的语义是一致的。

因为64位CPU一般都不需要高端内存(当然也可以支持),在地址空间划分上与32位CPU的差异较大,下图是一个X86_64的内核地址空间划分图:

  资料直通车:Linux内核源码技术学习路线+视频教程内核源码

学习直通车:Linux内核源码内存调优文件系统进程管理设备驱动/网络协议栈

内存管理;软件架构

内核内存管理的核心工作就是内存的分配回收管理,其内部分为2个体系:页管理和对象管理。页管理体系是一个两级的层次结构,对象管理体系是一个三级的层次结构,分配成本和操作对CPU cache和TLB的负面影响,从上而下逐渐升高。

页管理层次结构:由冷热缓存、伙伴系统组成的两级结构。负责内存页的缓存、分配、回收。

对象管理层次结构:由per-cpu高速缓存、slab缓存、伙伴系统组成的三级结构。负责对象的缓存、分配、回收。这里的对象指小于一页大小的内存块。

除了内存分配,内存释放也是按照此层次结构操作。如释放对象,先释放到per-cpu缓存,再释放到slab缓存,最后再释放到伙伴系统。

框图中有三个主要模块,即伙伴系统、slab分配器和per-cpu(冷热)缓存。他们的对比分析如下。

原文作者:极客重生

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

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

相关文章

mac制作ssl证书|生成自签名证书,nodejs+express在mac上搭建https+wss(websocket)服务器

注意 mac 自带 openssl 所以没必要像 windows 一样先安装 openssl,直接生成即可 生成 ssl/自签名 证书 生成 key # 生成rsa私钥,des3算法,server_ssl.key是秘钥文件名 1024位强度 openssl genrsa -des3 -out server_ssl.key 1024让输入两…

【前端】Vue2 脚手架模块化开发 -快速入门

🎄欢迎来到边境矢梦的csdn博文🎄 🎄本文主要梳理Vue2 脚手架模块化开发 🎄 🌈我是边境矢梦,一个正在为秋招和算法竞赛做准备的学生🌈 🎆喜欢的朋友可以关注一下🫰&#x…

iOS逆向进阶:iOS进程间通信方案深入探究与local socket介绍

在移动应用开发中,进程间通信(Inter-Process Communication,IPC)是一项至关重要的技术,用于不同应用之间的协作和数据共享。在iOS生态系统中,进程和线程是基本的概念,而进程间通信方案则为应用的…

【已解决】pycharm 突然每次点击都开新页面,关不掉怎么办?

今天在 pycharm 中写代码,突然发现,新开的文件不再原来的页面上,而是新增了页面,导致整个屏幕全都是新开的页面,最难受的是,关不掉! 无奈,我只能关闭 pycharm,重新双击…

openGauss学习笔记-55 openGauss 高级特性-全密态数据库

文章目录 openGauss学习笔记-55 openGauss 高级特性-全密态数据库55.1 连接全密态数据库55.2 创建用户密钥55.3 创建加密表55.4 向加密表插入数据并进行查询 openGauss学习笔记-55 openGauss 高级特性-全密态数据库 全密态数据库意在解决数据全生命周期的隐私保护问题&#xf…

Java LinkedList

简介 链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址。 链表可分为单向链表和双向链表。 在Java程序设计语言中,所有…

RabbtiMQ的安装与在Springboot中的使用!!!

一、安装Erlang与Rabbitmq 安装教程本教程是在centos8下试验的,其实linux系统的都差不多RabbitMQ官方:Messaging that just works — RabbitMQRabbitMQ是开源AMQP实现,服务器端用Erlang语言编写,Python、Ruby、 NET、Java、JMS、c…

机器学习笔记:轨迹驻留点 staypoint

1 定义 在轨迹数据分析中,"停留点"(Staypoint)是一个非常关键的概念,它反映了个体或物体在某一地点的停留行为。通常,在一段时间内,如果一个人或物体在一个较小的地理区域内的移动距离低于某个阈…

攻防世界-WEB-ics-05

打开靶机 只有设备维护中心可以点开 点标签得到新的url pageindex 想到文件包含漏洞(URL中出现path、dir、file、pag、page、archive、p、eng、语言文件等相关关键字眼 利用php伪协议查看源码 出现一段base64源码,进行转码得出源码 ?pagephp://filter…

Agisoft Metashape相机标定笔记

Lens Calibration(镜头标定) 使用Metashape进行自动相机标定是可能的。Metashape使用LCD显示屏作为标定目标(可选:使用打印的棋盘格图案,但需保证它是平坦的且单元格是正方形)。 相机标定步骤支持全相机标定矩阵的估计&#xff…

蓝桥杯打卡Day3

文章目录 吃糖果递推数列 一、吃糖果IO链接 本题思路:本题题意就是斐波那契数列&#xff01; #include <bits/stdc.h>typedef uint64_t i64;i64 f(i64 n) {if(n1) return 1;if(n2) return 2;return f(n-1)f(n-2); }signed main() {std::ios::sync_with_stdio(false);s…

kubernetes——ingress

简介 ingress: 是k8s内部的一个资源对象ingress controller -> ingress控制器&#xff1a; 是k8s里启动的一个pod&#xff0c;运行的是nginx的镜像&#xff0c;实现k8s内部的service&#xff08;ClusterIP类型&#xff09;的负载均衡 ingress 和ingress controller 的关…

docker容器运行成功但无法访问,原因分析及对应解决方案(最新,以Tomcat为例,亲测有效)

原因分析&#xff1a; 是否能访问当运行docker容器虚拟机&#xff08;主机&#xff09;地址 虚拟机对应的端口号是否开启或者防墙是否关闭 端口映射是否正确&#xff08;这个是我遇到的&#xff09; tomcat下载的是最新版&#xff0c;docker运行后里面是没有东西的&am…

单片机-蜂鸣器

简介 蜂鸣器是一种一体化结构的电子讯响器&#xff0c;采用直流电压供电 蜂鸣器主要分为 压电式蜂鸣器 和 电磁式蜂鸣器 两 种类型。 压电式蜂鸣器 主要由多谐振荡器、压电蜂鸣片、阻抗匹配器及共鸣箱、外壳等组成。多谐振荡器由晶体管或集成电路构成&#xff0c;当接通电源后&…

Java ArrayList

简介 ArrayList类示一个可以动态修改的数组&#xff0c;与普通数组的区别是它没有固定大小的限制&#xff0c;可以添加和删除元素。 适用情况&#xff1a; 频繁的访问列表中的某一元素只需要在列表末尾进行添加和删除某些元素 实例 ArrayList 是一个数组队列&#xff0c;提…

PostgreSQL本地化

本地化的概念 本地化的目的是支持不同国家、地区的语言特性、规则。比如拥有本地化支持后&#xff0c;可以使用支持汉语、法语、日语等等的字符集。除了字符集以外&#xff0c;还有字符排序规则和其他语言相关规则的支持&#xff0c;例如我们知道(‘a’,‘b’)该如何排序&…

移动安全测试框架-MobSF WINDOWS 环境搭建

安装python python-3.11.5-amd64.exe 安装Win64OpenSSL-3_1_2.exe 安装VisualStudioSetup.exe github下载安装包 https://github.com/MobSF/Mobile-Security-Framework-MobSF/archive/refs/heads/master.zip GitHub - MobSF/Mobile-Security-Framework-MobSF: Mobile Secur…

gismo程序示例:边长为 8 16 32 的长方体 受均布载荷

文章目录 前言一、一、8*32面 受均布载荷 二、最小的面&#xff08;8*16&#xff09;受均布载荷三、最大的面受均布载荷 前言 只是为方便学习&#xff0c;不做其他用途&#xff0c; 一、 一、8*32面 受均布载荷 /// This is an example of using the linear elasticity solver…

【进阶篇】Redis缓存击穿, 穿透, 雪崩, 污染详解

【进阶篇】Redis缓存穿击, 穿透, 雪崩, 污染详解 文章目录 【进阶篇】Redis缓存穿击, 穿透, 雪崩, 污染详解0. 前言大纲缓存穿击缓存穿透缓存雪崩缓存污染 1. 什么是缓存穿透&#xff1f;1.1. 发生原因1.2. 导致问题1.3. 解决方案 2. 什么是缓存击穿3.1. 发生原因3.1. 解决方案…

Spring-Cloud-Openfeign如何传递用户信息?

用户信息传递 微服务系统中&#xff0c;前端会携带登录生成的token访问后端接口&#xff0c;请求会首先到达网关&#xff0c;网关一般会做token解析&#xff0c;然后把解析出来的用户ID放到http的请求头中继续传递给后端的微服务&#xff0c;微服务中会有拦截器来做用户信息的…