内存管理的关键技术——反向映射机制

news2024/12/23 7:06:34

Cheetah,曾为U-boot社区和Linux内核社区提交过若干补丁,主要从事Linux相关系统软件开发工作,负责Soc芯片BringUp及系统软件开发,喜欢阅读内核源代码,在不断的学习和工作中深入理解内存管理,进程调度,文件系统,设备驱动等内核子系统。

为了系统的安全性,Linux内核将各个用户进程运行在各自独立的虚拟地址空间,用户进程之间通过虚拟地址空间相互隔离,不能相互访问,一个进程的奔溃不会影响到整个系统的异常也不会干扰到系统以及其他进程运行。

Linux内核可以通过共享内存的方式为系统节省大量内存,例如fork子进程的时候,父子进程通过只读的方式共享所有的私有页面。再比如通过IPC共享内存方式,各个不相干的进程直接可以共享一块物理内存等等。

我们都知道操作系统开启mmu之后cpu访问到的都是虚拟地址,当cpu访问一个虚拟地址的时候需要通过mmu将虚拟地址转化为物理地址,这叫做正向映射。而与本文相关的是反向映射,它主要是通过物理页来找到共享这个页的所有的vma对应的页表项,这是本文讨论的问题。

注:反向映射机制是Linux内核虚拟内存管理的难点也是理解内存管理的关键技术之一!!

内核资料直通车:最新Linux内核源码资料文档+视频资料icon-default.png?t=M85Bhttps://link.zhihu.com/?target=https%3A//docs.qq.com/doc/DTmFTc29xUGdNSnZ2

学习直通车:Linux内核源码/内存调优/文件系统/进程管理/设备驱动/网络协议栈icon-default.png?t=M85Bhttps://link.zhihu.com/?target=https%3A//ke.qq.com/course/4032547%3FflowToken%3D1040236

反向映射的发展

实际上在早期的Linux内核版本中是没有反向映射的这个概念的,那个时候为了找到一个物理页面对应的页表项就需要遍历系统中所有的mm组成的链表,然后对于每一个mm再遍历每一个vma,然后查看这个vma是否映射了这页,这个过程极其漫长而低效,有的时候不得不遍历完所有的mm然后才能找映射到这个页的所有pte。

后来人们发现了这个问题,就在描述物理页面的page结构体中增加一个指针的方式来解决,通过这个指针来找到一个描述映射这个页的所有pte的数组结构,这对于反向映射查找所有pte易如反掌,但是带来的是浪费内存的问题。

接着就在2.6内核的时候,内核大神们想到了复用page结构中的mapping字段,然后通过红黑树的方式来组织所有映射这个页的vma,形成了匿名页和文件页的反向映射机制。

但是后来匿名页的反向映射遇到了效率和锁竞争激烈问题,就促使了目前使用的通过avc的方式联系各层级反向映射结构然后将锁的粒度降低的这种方式。可以看到反向映射的发展是伴随着Linux内核的发展而发展,是一个不断进行优化演进的过程。

反向映射应用场景

那么为何在Linux内核中需要反向映射这种机制呢?它究竟为了解决什么样的问题而产生的呢?

试想有如下场景:
(1)一个物理页面被多个进程的vma所映射,系统过程中发生了内存不足,需要回收一些页面,正好发现这个页面是适合我们回收利用的,我们能够直接把这个页面还给伙伴系统吗?答案肯定是不能。因为这个页面被很多个进程所共享,我们必须做的事情就是断开这个页面的所以映射关系,这就是反向映射所做的事情。
(2)一些情况我们需要将一个页面迁移到另一个页面,但是牵一发而动全身,可能有一些进程已经映射这个即将要迁移的页面到自己的vma中,那么这个时候同样需要我们知道究竟这个页面被哪些vma所映射呢?这同样是反向映射所做的事情。

实际上,反向映射的主要应用场景为内存回收和页面迁移,当系统发生内存回收和页面迁移的时候,对于每一个候选页Linux内核都会判断是否为映射页,如果是,就会调用try_to_unmap 来解除页表映射关系,本文也主要来从try_to_unmap函数来解读反向映射机制。

如果我们在细致到其他的内核子系统会发现,在内存回收,内存碎片整理,CMA, 巨型页,页迁移等各个场景中都能发现反向映射所做的关键性的工作,所有理解反向映射机制在Linux内核中的实现是理解掌握这些子系统的基础和关键性所在,否则你即将不能理解这些技术背后的脊髓所在,所以说理解反向映射这种机制对于理解Linux内核内存管理是至关重要的!!!

匿名页的反向映射

匿名页的共享主要发生在父进程fork子进程的时候,父fork子进程时,会复制所有vma给子进程,并通过调用dup_mmap->anon_vma_fork建立子进程的rmap以及和长辈进程rmap关系结构:
主要通过anon_vma这个数据结构体中的红黑树将共享父进程的页的所有子进程的vma联系起来(通过anon_vma_chain 来联系对应的vma和av),当然这个关系建立比较复杂,涉及到vma,avc和av这些数据结构体。.

而在缺页异常do_anonymous_page的时候将page和vma相关联。

当内存回收或页面迁移的时候,内核路径最终会调用到:

try_to_unmap //mm/rmap.c ->rmap_walk ->rmap_walk_anon ->anon_vma_interval_tree_foreach(avc, &anon_vma->rb_root,pgoff_start, pgoff_end) ->rwc->rmap_one ->try_to_unmap_one

对于候选页,会拿到候选页相关联的anon_vma,然后从anon_vma的红黑树中遍历到所有共享这个页的vma,然后对于每一个vma通过try_to_unmap_one来处理相对应的页表项,将映射关系解除。

文件页的反向映射

文件页的共享主要发生在多个进程共享libc库,同一个库文件可以只需要读取到page cache一次,然后通过各个进程的页表映射到各个进程的vma中。

管理共享文件页的所以vma是通过address_space的区间树来管理,在mmap或者fork的时候将vma加入到这颗区间树中:
发生文件映射缺页异常的时候,将page和address_space相关联。

当内存回收或页面迁移的时候,内核路径最终会调用到:

try_to_unmap //mm/rmap.c ->rmap_walk ->rmap_walk_file ->vma_interval_tree_foreach(vma, &mapping>i_mmap,pgoff_start, pgoff_end) ->rwc->rmap_one

对于每一个候选的文件页,如果是映射页,就会遍历page所对应的address_space的区间树,对于每一个满足条件的vma,调用try_to_unmap_one来找到pte并解除映射关系。

ksm页的反向映射

ksm机制是内核将页面内容完全相同的页面进行合并(ksm管理的都是匿名页),将映射到这个页面的页表项标记为只读,然后释放掉原来的页表,来达到节省大量内存的目的,这对于host中开多个虚拟机的应用场景非常有用。

ksm机制中会管理两棵红黑树,一棵是stable tree,一棵是unstable tree,stable tree中的每个节点stable_node中管理的页面都是页面内容完全相同的页面(被叫做kpage),共享kpage的页面的页表项都会标记为只读,而且对于原来的候选页都会有rmap_item来描述他的反向映射(其中的anon_vma成员的红黑树是描述映射这个候选页的所有vma的集合),合并的时候会加入到对应的stable tree节点和链表中。

当内存回收或页面迁移的时候,内核路径最终会调用到:

try_to_unmap //mm/rmap.c ->rmap_walk ->rmap_walk_ksm //mm/ksm.c -> hlist_for_each_entry(rmap_item, &stable_node->hlist, hlist) ->anon_vma_interval_tree_foreach(vmac, &anon_vma->rb_root,0, ULONG_MAX) ->rwc->rmap_one

对于一个ksm页面,反向映射的时候,会拿到ksm页面对应的节点,然后遍历节点的hlist链表,拿到每一个anon_vma,然后就和上面介绍的匿名页的反向映射一样了,从anon_vma的红黑树中找到所有的vma,最后try_to_unmap_one来找到pte并解除映射关系。

总结

前面我们介绍了反向映射的三种类型,匿名页,文件页和ksm页的反向映射,分别通过page所对应的的vma, address_space, stable_node结构来查找vma。当然我们只是介绍了Linux内核中的反向映射的冰山一角,主要是try_to_unmap函数,其实每种反向映射各个数据结构建立的过程错综复杂,一篇文章三言两语也说不清楚,他们散落在Linux内核源代码的进程创建fork,内存映射mmap,缺页异常处理,文件系统等各个角落。

诚然,如果我们搞不清楚各种反正映射所对应的各种数据结构之间的关系,或者只是有一些概念上的了解,并没有真正掌握这种机制的实现原理,对于我们来理解Linux内核虚拟内存管理来说是一种障碍,不懂得反向映射内存管理 中的很多问题是搞不明白的!

 

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

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

相关文章

大数据技术——Flume实战案例

实战案例目录1. 复制和多路复用1.1 案例需求1.2 需求分析1.3 实现操作2. 负载均衡和故障转移2.1 案例需求2.2 需求分析2.3 实现操作3. 聚合操作3.1 案例需求3.2 需求分析3.3 实现操作1. 复制和多路复用 1.1 案例需求 使用 Flume-1 监控文件变动,Flume-1 将变动内容…

图文详解二维差分

目录 前言 一、 二维差分的定义 二、二维差分的使用 三、计算二维差分 四、ACWing 798. 差分矩阵 前言 一维二维前缀和详解 图文详解一维差分 一、 二维差分的定义 对于一个给定的二维数组 arr,它的二维差分数组 d 中 d[i][j] 可以用如下公式计算:…

命令执行-无字母数字webshell

命令执行-无字母数字webshell 我们看如下代码&#xff1a; <?php if(!preg_match(/[a-z0-9]/is,$_GET[shell])) {eval($_GET[shell]); }在命令执行中&#xff0c;我们经常会碰到过滤了字母和数字的情况&#xff0c;那如何才能绕过呢&#xff1f; 我的想法&#xff1a;通…

【数据结构】ArrayList的简单使用

文章目录ArrayList一些ArrayList常用的方法杨辉三角打扑克时的洗牌与摸牌ArrayList 上一次我们自己模拟实现了一下数据结构中的顺序表&#xff0c;当然在我们日常使用时不需要每次使用都自己模拟实现一遍&#xff0c;Java中提供了ArrayList类&#xff0c;我们直接导包就可以使…

如何使用 Delphi / Lazarus / C++ Builder 从 FastReport VCL 创建 Code 11 条码?

Fastreport是目前世界上主流的图表控件&#xff0c;具有超高性价比&#xff0c;以更具成本优势的价格&#xff0c;便能提供功能齐全的报表解决方案&#xff0c;连续三年蝉联全球文档创建组件和库的“ Top 50 Publishers”奖。 FastReport.VCL官方版下载https://www.evget.com/…

黑客动态播报 | 这种勒索方式,让付赎金毫无用处

入侵→加密→要赎金 黑客凭这套商业模式横行多年 受害者之所以前赴后继付赎金 是因为他们相信 给钱就能如愿拿到密钥 尽快恢复业务 可有的时候 自系统被加密的那一刻起 数据就拿不回来了 今年10月,网上出现了一种名为Cryptonite的开源勒索软件包。它使用Python编码,利…

SpringBoot 整合 Shiro 实现动态权限加载更新+ Session 共享 + 单点登录

一.说明 二.项目环境 二.编写项目基础类 三.编写Shiro核心类 四.实现权限控制 五.POSTMAN测试 六.项目源码 一.说明 Shiro是一个安全框架,项目中主要用它做认证,授权,加密,以及用户的会话管理,虽然Shiro没有SpringSecurity功能更丰富,但是它轻量,简单,在项目中通常业务…

报表设计-FineReport 配置MySQL5外接数据库

1. 概述 1.1 版本 报表服务器版本 功能变更 11.0 - 11.0.3 1&#xff09;首次配置外接数据库时&#xff0c;支持自行选择是否「迁移数据至要启用的数据库」 2&#xff09;迁移外接数据库的过程提示细化&#xff0c;方便用户了解迁移进度 1.2 功能简介 报表系统配置外接数…

推荐系统遇上深度学习(一四一)-[快手]移动端实时短视频推荐

今天给大家带来CIKM2022应用研究方向最佳论文-来自于快手团队的《Real-time Short Video Recommendation on Mobile Devices》&#xff0c;主要研究在移动端如何做到更好的短视频实时推荐&#xff0c;是一篇不错的落地经验分享的论文&#xff0c;一起来看一下。1、背景近几年来…

LeetCode 323周赛

2500. 删除每行中的最大值 给你一个 m x n 大小的矩阵 grid &#xff0c;由若干正整数组成。 执行下述操作&#xff0c;直到 grid 变为空矩阵&#xff1a; 从每一行删除值最大的元素。如果存在多个这样的值&#xff0c;删除其中任何一个。将删除元素中的最大值与答案相加。 …

【Leetcode】101. 对称二叉树、104. 二叉树的最大深度、226. 翻转二叉树

作者&#xff1a;一个喜欢猫咪的的程序员 专栏&#xff1a;《Leetcode》 喜欢的话&#xff1a;世间因为少年的挺身而出&#xff0c;而更加瑰丽。 ——《人民日报》 目录 101. 对称二叉树 104. 二叉树的最大深度 226. 翻转二叉树 101. 对称二…

DJ11 8086系列处理器(第一节课)

目录 一、8086/8088微处理器 二、8086/8088CPU的特点 1. 指令流水线 2. 内存分段管理 3. 支持多处理器系统 三、8088 CPU外部引脚及功能 1. 最小模式下的引脚 2. 最大模式下的引脚 四、8088/8086 CPU 的工作时序 1. 基本概念 2. 总线周期 一、8086/8088微处理器 二、…

软考中级系统集成项目管理工程师怎么自学备考

1、考试内容是什么&#xff1f; 2、备考前要准备什么&#xff1f; 3、如何高效备考&#xff1f; 一、考试内容是什么&#xff1f; 本考试设置的科目包括&#xff1a; &#xff08;1&#xff09;系统集成项目管理基础知识&#xff0c;考试时间为150分钟&#xff0c;笔试&am…

IB体育评估哪些内容?

"IB体育"这个词的内涵太广了&#xff0c;覆盖的课程也很多&#xff01;这个IB体育是一般体育课还是某个具体的IB科目呢&#xff1f;是MYP阶段的体育还是DP阶段的呢&#xff1f;其实很多人都是很懵&#xff0c;通过收集资料&#xff0c;可以分享一下&#xff0c;仅供参…

2022年虚拟电厂行业研究报

第一章 行业概况 虚拟电厂&#xff08;VPP, Virtual Power Plant&#xff09;本质上是将分布式电源&#xff08;发电&#xff09;、可控负荷&#xff08;用电&#xff09;、储能等利用计算机通信网络技术将其聚合成一个虚拟的集中式电厂&#xff0c;来为电网提供需求侧响应的“…

4个封神的电脑工具,颠覆你对免费白嫖的认知,干货奉上

闲话少说&#xff0c;直上干货。 1、TinyWow TinyWow虽说是国外网站工具&#xff0c;但不得不承认真的无敌好用&#xff0c;收纳工具超200个&#xff0c;完全免费&#xff0c;无任何弹屏广告&#xff0c;更为良心的是&#xff0c;不需要注册登录&#xff0c;随用随走&#xff0…

专业的方案公司阐述智能硬件产品开发的全过程

现在市场上的方案公司太多&#xff0c;让人应接不暇&#xff0c;当我们要开发一款智能硬件产品的时候&#xff0c;我们要如何去选择方案公司呢&#xff1f;又怎样判断方案公司是否则专业呢&#xff1f;下面沐渥带大家一起来了解下智能硬件产品开发的全过程&#xff0c;大家就知…

Ubuntu 18.0.4 SonarQube-7.1.x 安装教程 以及错误总结

Ubuntu 18.0.4 SonarQube-7.1.x 安装教程 docker安装未成功 zip安装 1. 下载地址 sonarQube最新版下载地址&#xff1a;&#xff08;最新版不支持mysql&#xff09;https://www.sonarqube.org/downloads/7.1版本下载地址&#xff1a;​ ​https://binaries.sonarsource.com…

【UE4 第一人称射击游戏】10-添加冲刺功能

上一篇&#xff1a; 【UE4 第一人称射击游戏】09-添加蹲伏功能 本篇效果&#xff1a; 步骤&#xff1a; 1.在“Character”文件夹内添加一个混合空间 骨架选择“Swat_Skeleton” 命名为“Sprint_BS” 双击打开“Sprint_BS”&#xff0c;将水平和垂直坐标名称分别设为“Direct…

【java】HashMap底层原理实现原理及面试题

目录一.哈希表(散列)1.什么是哈希表2.什么是哈希冲突(面试题)3.解决哈希冲突的方法(面试题)(1) 开放地址法① 线性探查②二次探查③随机探查(2) 再哈希法(3) 链地址法(4)建立公共溢出区二.HashMap1.HashMap的hash()算法(面试)(1)为什么不是h key.hashCode()直接返回&#xff0…