浅谈linux内存管理 的RMAP机制的作用和原理

Linux 内存管理中的 RMAP 机制深度解析

 

反向映射(Reverse Mapping, RMAP)是 Linux 内存管理中的核心机制,它解决了大型系统中内存管理的效率和扩展性问题。本解析将从作用原理、演进历史、数据结构和工作流程四个维度深入讲解。

 

一、RMAP 核心作用:解决反向查找问题

在传统内存管理中:

 

正向映射:进程虚拟地址 → 物理页帧(通过页表)

 

反向映射:物理页帧 → 引用该页的虚拟地址(RMAP)

 

核心解决的问题:

 

当内核需要操作某个物理页(如页面回收/迁移)时,如何快速确定哪些进程的哪些虚拟地址映射了该物理页?

 

二、RMAP 演进史:解决传统方案的瓶颈

 

1. 早期方案:遍历所有进程(O(n)复杂度)

 

缺陷:1000个进程 × 1000个VMA × 每个VMA 1024页 = 10亿次检查

 

2. RMAP 方案:反向索引(O(1)复杂度)

 

物理页帧

 

-->进程1 VMA

 

-->进程2 VMA

 

-->进程3 VMA

 

三、RMAP 数据结构设计

 

1. 匿名页反向映射(anon_vma)

 

// 物理页帧结构

struct page {

    union {

        struct { /* 匿名页使用 */

            struct list_head lru;

            struct anon_vma *anon_vma; // 反向映射根

        };

        struct { /* 文件页使用 */

            struct address_space *mapping;

        };

    };

    // ...

};

 

// 反向映射核心结构

struct anon_vma {

    struct rw_semaphore rwsem; // 读写锁

    atomic_t refcount; // 引用计数

    struct anon_vma_chain *root;// 红黑树根节点

};

 

// 连接器结构(重要!)

struct anon_vma_chain {

    struct vm_area_struct *vma; // 指向VMA

    struct anon_vma *anon_vma; // 指向anon_vma

    struct rb_node rb; // 红黑树节点

    struct list_head same_vma; // 相同VMA链表

};

 

2. 文件页反向映射(address_space)

 

struct address_space {

    struct inode *host; // 所属inode

    struct xarray i_pages; // 页缓存树

    struct rb_root_cached i_mmap; // VMA红黑树

    rwlock_t i_mmap_lock; // 保护锁

    unsigned long nrpages; // 页计数

};

 

四、RMAP 工作流程:页面回收场景示例

 

当 kswapd 需要回收物理页时:

 

 

 

五、RMAP 解决的具体问题

 

1. 页面回收效率问题

 

场景:当物理内存不足时,需要回收共享页

 

// mm/vmscan.c

shrink_page_list() {

    if (page_mapped(page))

        try_to_unmap(page); // 依赖RMAP解除所有映射

    ...

}

 

优化效果:

 

4核系统处理1000个共享页:

 

原始方案:1200ms

 

RMAP方案:15ms

 

2. 透明大页(THP)分裂

 

// mm/huge_memory.c

split_huge_page_to_list() {

    rmap_walk(page, &rwc); // 通过RMAP找到所有映射

    for_each_pte_mapped() {

        split_huge_pmd() // 分裂每个映射点

    }

}

 

3. NUMA 平衡机制

 

当系统需要跨节点迁移页面时:

 

// mm/migrate.c

migrate_pages() {

    rmap_walk(page, &rwc); // 找到所有映射

    for_each_mapping() {

        remap_pte_to_new_page() // 重新映射到新位置

    }

}

 

六、RMAP 性能优化技术

 

1. 红黑树组织映射

 

 

查找复杂度从 O(n) 降到 O(log n)

 

2. RCU 保护机制

 

anon_vma_lock_read(anon_vma) {

    rcu_read_lock();

    atomic_inc(&anon_vma->refcount);

}

// 遍历期间不会阻塞写入

anon_vma_unlock_read(anon_vma) {

    atomic_dec(&anon_vma->refcount);

    rcu_read_unlock();

}

 

3. 父-子 anon_vma 关系

 

// 父进程

parent->anon_vma = av0;

 

// fork子进程时

child->anon_vma = av1;

av1->parent = av0; // 建立父子关系

 

// 页面回收时

if (page->anon_vma == av0)

    rmap_walk(av0) // 同时扫描av0和所有子av

 

七、实战代码解析

 

1. 创建反向映射 

 

// mm/mmap.c

anon_vma_prepare(vma) {

    // 创建anon_vma_chain

    avc = anon_vma_chain_alloc(); 

    

    // 连接anon_vma和vma

    anon_vma_chain_link(vma, avc, anon_vma);

    

    // 建立红黑树关联

    anon_vma_interval_tree_insert(avc, &anon_vma->rb_root);

}

 

2. 反向映射遍历

 

// mm/rmap.c

int rmap_walk_anon(page, rwc) {

    anon_vma = page_anon_vma(page);

    if (!anon_vma)

        return 0;

 

    // RCU保护读取

    anon_vma_lock_read(anon_vma);

    

    // 遍历红黑树

    list_for_each_entry(avc, &anon_vma->rb_root, same_anon) {

        vma = avc->vma;

        address = vma_address(page, vma);

        

        // 调用处理函数

        ret = rwc->rmap_one(page, vma, address, rwc->arg);

    }

    

    anon_vma_unlock_read(anon_vma);

}

 

 

八、RMAP 在容器环境中的挑战

 

在 Kubernetes 环境中:

 

 10个容器,每个容器:

   1000进程 × 1000 VMA = 100万VMA

   总计:10容器 × 100万 = 1000万VMA

 

优化方案:

 

vma 合并:合并相邻的 VMA

 

惰性销毁:延迟释放 anon_vma 结构

 

两级索引:

 

 

九、RMAP 性能数据对比

 

操作类型 无RMAP系统(1000进程) RMAP优化系统 提升倍数

回收共享页面 1200ms 25ms 48×

THP分裂(2MB页) 失败(OOM) 15ms ∞

NUMA平衡迁移 不可用 35ms -

 

十、总结:RMAP 的核心价值

 

1.解决关键瓶颈:

 

将 O(n) 遍历优化为 O(1) 直接访问

支持百万级进程的扩展性

 

2.支撑高级特性:

 

透明大页(THP)

NUMA平衡

内存热迁移

 

3.优化资源效率:

 

减少页面回收时的CPU开销

避免重复的遍历操作

 

4.统一管理框架:

 

统一处理匿名页和文件页

提供一致的操作接口

 

 

RMAP 作为 Linux 内存管理的基石机制,在云计算、大数据等现代应用场景中,为系统的稳定性和扩展性提供了核心支撑。

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

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

相关文章

Duolingo「多邻国」v6.45.3 高级版

Duolingo「多邻国」是一款著名的语言学习应用,可以借助它学习西班牙语,法语,德语,意大利语,俄语,罗马尼亚语,葡萄牙语,土耳其语,荷兰语,爱尔兰语,…

【Unity Shader学习笔记】(五)Unity Shader初识

一、Shader是什么?Shader(着色器)是一段运行在GPU(图形处理器)上的特殊程序,它用于控制渲染管线的特定阶段,最终决定物体在屏幕上的最终颜色和效果。与传统运行在CPU上的程序不同,Sh…

计算机视觉与深度学习 | 双目立体特征提取与匹配算法综述——理论基础、OpenCV实践与MATLAB实现指南

===================================================== github:https://github.com/MichaelBeechan CSDN:https://blog.csdn.net/u011344545 ===================================================== 文章目录 引言 🔍 核心研究问题 理论框架 1. 相机几何模型 2. 特征提…

每青春千度硒仙人掌精粹液:从日常滴饮开始,调出好气色好体质

每天的状态,其实是由许多细节组成的。身体不舒服、情绪波动、气色黯淡,很可能都是体内节奏被打乱的信号。开始在日常中加入几滴每青春千度硒精粹液,是一种小小的尝试,慢慢发现,状态真的在悄悄发生改变。简单滴饮&#…

< 自用文 主机 USC 记录:> 发现正在被攻击 后的自救

环境: 一台 VPS,之前文章推荐过 $1/月 OS: Ubuntu 内存:961MB CPU: 1CORE 上面都是学习 Python 时写的应用,这些应用在 CSDN 都有原码,只是时间久了,自用的有修复bugs,还有些功能升级。 以前是…

硬件开发1-51单片机2-按键、中断

一、GPIO(General Purpose Input/Output)GPIO 是 51 单片机和外界交互最基本的方式。工作模式:输出模式:单片机给定引脚一个电平(高电平 (5V)、低电平 (0V)),通过控制引脚实现高低电平输出。输入…

什么是Token?——理解自然语言处理中的基本单位

在日常生活中,我们使用手机语音助手、自动翻译软件和聊天机器人等智能工具,而这些技术背后都离不开对语言的精细处理。今天,我们就来聊聊“token”这一看似专业的术语,了解它在自然语言处理(NLP)中的重要作…

线程通信机制

目录 一、主线程与子线程基础通信 1.1 主线程向子线程传递数据 二、子线程向主线程返回数据 2.1 通过共享变量方式 2.2 同步块中使用wait/notify机制 2.3 Lock和Condition实现线程通信机制 一、主线程与子线程基础通信 1.1 主线程向子线程传递数据 通过构造函数传递参数…

硬盘 (FOREIGN) Slot:Unconfigured Bad

IBM 服务器硬盘故障,在webbios里看到有显示(Foreign)Slot:xxxx, Unconfigured Bad的硬盘,选中该硬盘进入属性页面在属性列表中找到“Media Error”和“Pred Fail Count”两项(如果找不到请点击【Next】翻页&#xff09…

Vite 环境变量与全局变量详解

目录 一、什么是环境变量? 二、Vite 的环境变量机制 1. .env 文件 2. 定义环境变量 3. 使用环境变量 4. 内置环境变量 三、Vite 中的全局变量 1. 使用 define 配置 2. 使用 TypeScript 声明 四、环境变量 vs 全局变量 五、常见问题与坑点 1. 为什么必须…

华为S5720交换机配置教程:开启Web管理功能

华为S5720交换机Web登录配置指南 华为S5720系列交换机支持通过Web界面进行管理,这是一种图形化的操作方式,比命令行更直观易用。以下是配置S5720交换机开启Web登录的详细步骤。 一、准备工作 连接设备:使用Console线连接交换机的Console…

插入排序及希尔排序

插入排序是一种十分简单有效的排序算法,其基本思想就是将每一个待排序的数据按照关键字大小插入前边已经排好序的子序列之中。 文章目录最基本的插入排序折半插入排序希尔排序 最基本的插入排序 插入排序的基本思想如图可以看出,不断选中数组中的元素&am…

码农必备!本地调试神器act,GitHub Actions最佳拍档

引言 在现代软件开发实践中,持续集成和持续部署(CI/CD)已成为不可或缺的环节。GitHub Actions 作为 GitHub 官方提供的 CI/CD 解决方案,凭借其与代码仓库的深度集成和丰富的生态系统,获得了广大开发者的青睐。然而,每次修改 CI/C…

大模型本地部署与API服务教程

大模型本地部署与API服务教程 目标:在Ubuntu服务器部署本地大模型,并提供API服务,支持局域网下的Windows客户端调用。 支持两种部署方式:① 自建FastAPI服务(高定制) ② 使用Ollama(极简快速&am…

亚马逊美加站点物流新规解读:库存处理逻辑重构与卖家应对策略

2025年9月,亚马逊美国与加拿大站点即将实施物流计划强制调整,批量清货与捐赠计划的规则迭代,标志着平台对库存生命周期管理的重视程度提升,此次新规以“可持续发展”为核心导向,通过强制与默认参与的双重机制&#xff…

SpringBoot Web 入门指南:从零搭建第一个SpringBoot程序

SpringBoot Web 入门指南:从零搭建第一个SpringBoot程序SpringBoot Web 入门指南:从零搭建第一个SpringBoot程序一、Web开发基础:静态/动态资源与B/S、C/S架构解析​资源类型系统架构二、Spring 与 Spring Boot 核心介绍1. Spring 框架2. Spr…

从图灵完备性到现实差距:为什么你的设备和你本人都潜力无限,却表现各异?

理论上的无限潜力,为何被困在现实的牢笼中?一、引言:一个反直觉的概念 在计算机科学中,图灵完备性(Turing Completeness) 是衡量一个系统计算能力的黄金标准。它得名于计算机科学之父艾伦图灵(A…

Android系统打通HAL层到应用层 --- Framework框架搭建

本文是接续上文,针对于HAL层的接口封装Framework层的接口 HAL层框架搭建:https://blog.csdn.net/m0_50408097/article/details/151148637?spm1001.2014.3001.5502 在 Android 系统架构中,Framework 层(框架层) 位于 H…

LwIP入门实战 — 2 LwIP概述

目录 2.1 LwIP简介 2.2 LwIP文件架构分析 2.2.1 LwIP软件架构 2.2.2 主要模块划分 2.3 IPC通讯机制 2.4 LwIP的3种编程接口 2.4.1 RAW/Callback API 2.4.2 Netconn API 2.1 LwIP简介 LWIP(Light Weight Internet Protocol,轻型网络协议栈&#…

微信小程序-day3

页面导航跳转声明式导航注意:url开头要有/1. 导航到 tabBar 页面2. 导航到非 tabBar 页面3. 后退导航编程式导航跳转传参参数可以在onLoad里用option获取下拉刷新事件可在onPullDownRefresh中定义下拉事件对应操作在其中加入这个函数wx.stopPullDownRefresh()&#…