Linux内存管理系统性总结

Linux内存管理系统性总结

内存管理核心架构图

进程虚拟地址空间
页表机制
物理内存分配
SLAB分配器
内核对象
用户空间
虚拟内存区域 VMA
文件映射
匿名映射
页面回收
反向映射
交换机制

详细分析

1. 页表机制(多级页表转换)

核心功能:虚拟地址到物理地址的转换和内存保护

四级页表结构(x86_64)

// arch/x86/include/asm/pgtable_types.h
typedef struct { pgdval_t pgd; } pgd_t;  // 页全局目录
typedef struct { p4dval_t p4d; } p4d_t;  // 页四级目录
typedef struct { pudval_t pud; } pud_t;  // 页上级目录
typedef struct { pmdval_t pmd; } pmd_t;  // 页中间目录
typedef struct { pteval_t pte; } pte_t;  // 页表项

地址转换流程

CPU虚拟地址PML4表PDP表PD表PT表物理内存使用bits 47-39索引返回PDP基址使用bits 38-30索引使用bits 29-21索引使用bits 20-12索引物理地址 + 偏移(bits 11-0)CPU虚拟地址PML4表PDP表PD表PT表物理内存

关键机制

  1. 大页支持

    • 2MB大页:PMD直接指向物理页
    • 1GB大页:PUD直接指向物理页
    • 减少TLB miss,提升性能
  2. 写时复制(CoW)

    // mm/memory.c
    static vm_fault_t do_wp_page(struct vm_fault *vmf)
    {// 1. 检查是否共享页// 2. 分配新物理页// 3. 复制内容// 4. 更新页表项
    }
    
  3. 缺页处理

    // arch/x86/mm/fault.c
    void do_page_fault(struct pt_regs *regs, unsigned long error_code)
    {// 调用链:// handle_mm_fault() -> __handle_mm_fault() -> handle_pte_fault()
    }
    
  4. TLB
    4.1 定位:CPU内部的硬件缓存(通常为SRAM)
    4.2 作用:缓存最近使用的页表条目(PTE)
    4.3 性能价值:
    (1) 页表访问需4次内存访问(4级页表)
    (2) TLB访问仅需1-3个CPU周期(比内存快100倍+)

2. 伙伴系统(Buddy System)

核心功能:管理物理页帧的分配与释放,解决外部碎片

数据结构

// mmzone.h
struct zone {struct free_area free_area[MAX_ORDER];  // 11个阶(0-10)
};struct free_area {struct list_head free_list[MIGRATE_TYPES];unsigned long nr_free;
};

分配流程

alloc_pages
所需阶是否有空闲
从对应链表分配
向上查找更高阶
找到空闲块?
分裂块并分配
尝试回收或OOM

迁移类型

  1. MIGRATE_UNMOVABLE:内核核心数据结构
  2. MIGRATE_MOVABLE:用户空间页面
  3. MIGRATE_RECLAIMABLE:可回收页面
  4. MIGRATE_PCPTYPES:per-CPU页面

关键操作

// mm/page_alloc.c
static struct page *__rmqueue(struct zone *zone, unsigned int order,int migratetype)
{// 1. 尝试首选迁移类型// 2. 失败时尝试fallback类型
}
3. SLAB分配器

核心功能:高效分配内核小对象,减少内存碎片

三级缓存结构

kmem_cache
SLAB列表
满SLAB
部分空SLAB
空SLAB
Per-CPU缓存

关键数据结构

// mm/slab.h
struct kmem_cache {unsigned int size;        // 对象实际大小unsigned int object_size; // 对象原始大小struct kmem_cache_node **node;  // Per-NODE缓存struct array_cache __percpu *cpu_cache; // Per-CPU缓存
};struct slab {struct list_head list;   // SLAB链表void *s_mem;            // 第一个对象地址unsigned int active;     // 活跃对象数
};

分配流程

kmallocPer-CPU缓存Partial SLAB伙伴系统请求对象立即返回对象获取一批对象提供对象分配新SLAB页返回新页初始化对象alt[Partial SLAB可用]返回对象alt[CPU缓存中有空闲对象-]kmallocPer-CPU缓存Partial SLAB伙伴系统
4. 虚拟内存区域(VMA)

核心功能:管理进程的虚拟地址空间布局

数据结构

// mm_types.h
struct vm_area_struct {unsigned long vm_start;     // 起始地址unsigned long vm_end;       // 结束地址struct mm_struct *vm_mm;    // 所属内存结构pgprot_t vm_page_prot;      // 访问权限unsigned long vm_flags;     // 标志位struct rb_node vm_rb;       // 红黑树节点const struct vm_operations_struct *vm_ops; // 操作函数集struct file *vm_file;       // 映射的文件
};

VMA类型

  1. 文件映射

    • 映射文件到内存(mmap)
    • 缺页时从文件系统读取(filemap_fault)
  2. 匿名映射

    • 堆/栈空间
    • 缺页时分配零页(do_anonymous_page)

VMA管理

进程内存描述符 mm_struct
VMA红黑树
VMA链表
快速查找
顺序遍历

反向映射

// mm/rmap.c
struct anon_vma {struct rw_semaphore rwsem;struct rb_root rb_root;  // 关联的VMA
};
5. 内存回收机制

核心组件

  1. kswapd守护进程:后台回收
  2. 直接回收:分配时触发
  3. OOM Killer:内存耗尽处理

LRU算法

// mmzone.h
enum lru_list {LRU_INACTIVE_ANON = 0,LRU_ACTIVE_ANON = 1,LRU_INACTIVE_FILE = 2,LRU_ACTIVE_FILE = 3,LRU_UNEVICTABLE = 4,NR_LRU_LISTS
};

回收流程

文件页
匿名页
页面回收触发
页面类型
是否脏页
写回磁盘
直接回收
交换到swap
释放页面

系统级协作流程

用户进程内核页表伙伴系统SLABVMA管理malloc(申请内存)kmalloc返回对象alloc_pages返回页面alt[小对象][大对象]首次访问内存触发缺页异常查找VMA区域从文件读取分配物理页alt[文件映射][匿名映射]建立映射用户进程内核页表伙伴系统SLABVMA管理

关键源码路径

  1. 页表机制

    • arch/x86/mm/fault.c(缺页处理)
    • mm/memory.c(页表操作)
  2. 伙伴系统

    • mm/page_alloc.c(核心分配逻辑)
  3. SLAB分配器

    • mm/slub.c(SLUB实现)
    • mm/slab_common.c(通用接口)
  4. 虚拟内存管理

    • mm/mmap.c(VMA创建/删除)
    • mm/vmalloc.c(非连续内存分配)
  5. 内存回收

    • mm/vmscan.c(页面回收)
    • mm/swap_state.c(交换管理)

性能优化技术

  1. Per-CPU缓存:SLAB和伙伴系统均实现
  2. 预读机制:文件映射缺页时预加载
  3. 透明大页(THP):自动合并小页
  4. 内存压缩(zswap):减少交换I/O
  5. cgroup内存控制:容器级隔离

内存利用率优化技术

这是内存管理艺术的核心,通过各种技术减少浪费(碎片),让有限物理内存服务更多进程和数据:

1,分页:

1.1 基础: 允许物理内存以页为单位非连续分配,减少外部碎片。

1.2 按需分配: 进程申请大量内存时,操作系统通常只建立虚拟地址空间的映射,并不立即分配物理页。直到进程首次访问该页面触发页面故障时,才分配物理页帧并建立映射。这避免了分配但未使用的内存浪费。

2,虚拟内存:

2.1 核心思想: 利用磁盘空间(交换区/页文件)扩展物理内存。

2.2 换页: 当物理内存不足时,操作系统选择一些“不活跃”的内存页(页面置换算法如LRU, Clock, LFU等决定),将其内容写入磁盘,释放其物理页帧供其他进程使用。

2.3 效果: 使得进程的虚拟地址空间可以远大于物理内存,允许多个大型进程同时运行(尽管部分在磁盘上)。极大地提高了物理内存的利用率。

3,写时复制:

3.1 场景: fork()系统调用创建子进程,或共享内存映射。

3.2 机制: 初始时,父子进程共享相同的物理页帧,并将这些页标记为只读。当任何一方试图写入共享页时,触发页面故障。内核捕获此故障,为该进程复制一个新物理页帧,复制原内容,并更新该进程的页表映射为可写。然后恢复进程执行写入操作。

3.3 优势: 避免了在fork()后立即复制整个进程地址空间的巨大开销,大量共享的只读页(如代码段)无需复制。只有真正被修改的页才需要物理复制。显著节省内存。

4,内存压缩:

机制: 在物理内存紧张但尚未达到需要换页的程度时,内核将多个“可压缩”的、最近未使用的页内容压缩存储在一个物理页帧中,释放出空闲页帧。

优势: 比换页到磁盘快得多(磁盘I/O慢),能缓解内存压力,推迟甚至避免昂贵的换页操作,提高响应速度。

5,高效的内存分配器:

目标: 管理堆内存,减少内部碎片和外部碎片,提高分配/释放速度。

策略:

Slab分配器: 针对内核对象(如task_struct, inode等频繁创建销毁的小对象),预分配不同大小的Slab缓存,对象从Slab中快速分配释放,避免反复向通用分配器申请,减少碎片。

伙伴系统: 管理物理页帧分配,按2的幂次大小组织空闲链表,易于合并相邻空闲块,减少外部碎片。

用户空间分配器: 如glibc的ptmalloc, jemalloc, tcmalloc,采用不同策略(如线程本地缓存、大小分级、惰性合并)来优化多线程下的性能和碎片。

6,共享内存:

机制: 允许多个进程将同一块物理内存映射到各自的虚拟地址空间。

优势: 进程间通信最高效的方式,避免了数据复制。节省物理内存(一份数据供多个进程访问)。常用于数据库、科学计算等需要大量数据共享的场景。

7, 内存过量使用:

机制: 允许系统承诺分配的内存总量超过实际物理内存+交换空间的总和。依赖于程序不会同时访问所有已分配内存的特性(局部性原理)和高效的换页机制。

风险与平衡: 如果所有进程同时大量访问“承诺”的内存,会导致严重的抖动(频繁换页),性能急剧下降。操作系统需要谨慎监控和策略来管理风险。

总结表格

组件核心功能数据结构优化技术
页表机制地址转换与保护pgd_t, pte_tTLB, 大页
伙伴系统物理页帧管理zone, free_area迁移类型, per-CPU缓存
SLAB分配器小对象高效分配kmem_cache, slabCPU缓存, 对象重用
VMA管理虚拟地址空间布局vm_area_struct红黑树, 反向映射
内存回收内存资源回收lruvec, anon_vmaLRU算法, 交换压缩

此架构实现了从进程虚拟地址空间到物理内存的完整映射,通过多级缓存和智能回收策略,在保证隔离性和安全性的同时,最大化内存利用率和访问性能。

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

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

相关文章

MySQL 运算符实战:9 道经典练习题解析

MySQL 运算符实战:9 道经典练习题解析 运算符是 MySQL 查询的 “灵魂”,灵活运用各类运算符能让数据筛选更加精准高效。本文通过 9 道实战练习题,详解逻辑运算符、比较运算符及模糊匹配的用法,帮你快速掌握运算符的核心应用场景。…

【R语言】更换电脑后,如何在新设备上快速下载原来设备的 R 包?

【R语言】更换电脑后,如何在新设备上快速下载原来设备的 R 包? 在日常使用 R 进行数据分析时,我们往往会安装很多包(packages),一旦更换电脑,手动一个一个重新安装会非常麻烦。本文介绍一种简单…

如何在 Ubuntu 24.04 或 22.04 LTS 上安装 PowerShell

在本教程中,我们将学习如何在 Ubuntu 24.04 Noble 或 22.04 Jammy JellyFish Linux 中通过命令终端安装 Microsoft Windows PowerShell。 Windows PowerShell 既是一个命令行外壳程序,也是一种脚本语言。它拥有超过 130 个遵循一致语法和命名约定的命令行工具,称为 cmdlet(…

基于支持向量机的数据回归预测(libsvm) SVM

一、作品详细简介 1.1附件文件夹程序代码截图 全部完整源代码,请在个人首页置顶文章查看: 学行库小秘_CSDN博客​编辑https://blog.csdn.net/weixin_47760707?spm1000.2115.3001.5343 1.2各文件夹说明 1.2.1 main.m主函数文件 这段 MATLAB 代码实现…

Flowith-节点式GPT-4 驱动的AI生产力工具

本文转载自:Flowith-节点式GPT-4 驱动的AI生产力工具 - Hello123工具导航 ** 一、节点式 AI 工作流革新者:Flowith 深度解析 二、产品核心定位 Flowith 是一款基于 GPT-4 Turbo 的节点式 AI 生产力工具,突破传统单线程聊天模式&#xff0c…

MySQL的事务日志:

目录 redo(重做日志): 特点: 组成: 整体流程: redo log buffer与redo log file之间的刷盘策略: 异步刷盘: 同步刷盘: 拆中策略: undo(回…

JavaScript 中 throw error 与 throw new Error(error) 的用法及区别,分别适合什么场景使用?

JavaScript 中 throw error 与 throw new Error(error) 的用法及区别 在 JavaScript 中,throw 关键字用于抛出异常。当代码遇到某些错误或异常情况时,可以通过抛出错误来通知程序,方便后续的错误处理。尽管 throw 的使用看似简单&#xff0c…

鸿蒙自带组件效果大全

图形变换-视效与模糊-通用属性-ArkTS组件-ArkUI(方舟UI框架)-应用框架 - 华为HarmonyOS开发者 注意:找到需求效果之后先对一下版本 视距 图像效果 图片裁剪 颜色渐变 前景属性设置 外描边设置: 视效设置: 组件内容模糊 运动模糊 点击回弹效果…

ISP算法如何优化提升成像质量

ISP算法通过多维度技术协同优化成像质量,核心优化路径如下:一、降噪与细节增强‌AI驱动降噪‌深度学习模型实时识别噪点模式,暗光场景信噪比提升5倍以上,同时保留纹理细节。时空域联合降噪技术抑制运动模糊,鬼影消除率…

单例模式及优化

单例模式是一种创建型设计模式,其核心是确保一个类在程序中只能存在唯一实例,并提供一个全局访问点。这种模式适用于需要集中管理资源(如日志、配置、连接池)的场景,避免资源冲突和重复创建的开销。 一、介绍 类型 单例…

Dockerfile优化指南:利用多阶段构建将Docker镜像体积减小90%

更多如果你已经跟随我们之前的教程,亲手将自己的应用装进了Docker这个“魔法盒子”,那你可能很快就会遇到一个幸福但又尴尬的烦恼:你亲手构建的Docker镜像,竟然像一个塞满了石头和棉被的行李箱,臃肿不堪,笨…

英文PDF翻译成中文怎么做?试试PDF翻译工具

在全球化快速发展的时代,跨语言交流变得愈发频繁,无论是学术研究、商务合作还是日常学习,都离不开一个高效、准确的翻译工具。尤其是对于PDF文件的翻译需求,更是日益增长。今天,就让我们一起深入了解几款在PDF翻译领域…

macOS使用brew切换Python版本【超详细图解】

目录 一、更新Homebrew仓库 二、安装pyenv 三、将pyenv添加到bash_profile文件中 四、使.bash_profile文件的更改生效 五、安装需要的Python版本 六、设置全局使用的Python版本 七、检查Python版本是否切换成功 pyenv常用命令 一、更新Homebrew仓库 brew update 这个…

[矩阵置零]

初始思路分析 这段代码实现了将矩阵中元素为0的行和列全部置零的功能。主要思路是使用标记数组记录需要置零的行和列。以下是详细分析&#xff1a; 1. 初始化阶段 int m matrix.size(); int n matrix[0].size(); vector<bool> row(m), col(n);获取矩阵的行数m和列数n创…

redis-集成prometheus监控(k8s)

一. 简介&#xff1a; 关于redis的简介和部署&#xff0c;可以参考单独的文章redis-sentinel基础概念及部署-CSDN博客&#xff0c;这里就不细说了。这里只讲讲如何在k8s中部署export并基于prometheus做redis的指标采集。 二. 实现方式&#xff1a; 首先我们需要先部署exporter…

OVS:ovn为什么默认选择Geneve作为二层隧道网络协议?

首先确认 Geneve 是一种封装协议,可能提供比 VLAN 或 VXLAN 更灵活的扩展能力,这对 OVN 的多租户场景很重要。可能需要支持更多元数据字段,比如携带网络策略信息,这符合 SDN 集中控制的需求。 性能方面需要考虑封装效率和硬件支持情况,虽然 Geneve 头部稍大,但现代网卡的…

grep命令要点、详解和示例

grep技术要点 1) 工作模型&#xff08;3 件事&#xff09; 输入&#xff1a;从文件或标准输入&#xff08;-&#xff09;读入&#xff0c;一次按“行”处理&#xff08;除非用 -z 改成以 NUL 作为“行”分隔&#xff09;。匹配&#xff1a;把每一行拿去和模式&#xff08;patte…

nVidia Tesla P40使用anaconda本地重编译pytorch3d成功加载ComfyUI-3D-Pack

背景 自己用的是nVidia Tesla P40&#xff0c;垃圾佬专属卡 使用下面的由YanWenKun提供的ComfyUI-3D-Pack预安装环境&#xff0c;但在本地编译pytorch3d这一步出错&#xff0c;后面有出错信息&#xff0c;如果有和我一样的卡一样的问题&#xff0c;参看此文的解决方法 老版本…

网络基础——协议认识

文章目录网络基础网络的发展——引出一些概念协议认识初识协议协议分层协议分层的模型再谈协议为什么要有TCP/IP协议TCP/IP协议的宏观认识宏观理解TCP/IP协议和操作系统的关系协议的真正本质网络基础 本篇文章&#xff0c;我们将正式进入网络部分的学习。这是网络部分的第一篇…

云原生俱乐部-RH134知识点总结(2)

这一章的内容也会比较多&#xff0c;因为预期三篇文章更完RH134系列&#xff0c;所以每章安排的内容都比较多&#xff0c;并且RH134上面的都是重点&#xff0c;一点也不好写。昨天一天将RH124系列写完了&#xff0c;今天争取将RH134系列写完。至于我为什么要着急将这些写完&…