当前位置: 首页 > news >正文

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.xdnf.cn/news/1321633.html

相关文章:

  • Orange的运维学习日记--45.Ansible进阶之文件部署
  • 获粤港澳大湾区碳足迹认证:遨游智能三防手机赋能绿色通信
  • LeetCode:无重复字符的最长子串
  • 实践笔记-VSCode与IDE同步问题解决指南;程序总是进入中断服务程序。
  • LAMP 架构部署:Linux+Apache+MariaDB+PHP
  • 规避(EDR)安全检测--避免二进制文件落地
  • 云计算- KubeVirt 实操指南:VM 创建 、存储挂载、快照、VMI全流程 | 容器到虚拟机(镜像转换/资源调度)
  • 前端处理导出PDF。Vue导出pdf
  • 王树森深度强化学习DRL(三)围棋AlphaGo+蒙特卡洛
  • STRIDE威胁模型
  • 新手向:Java方向讲解
  • Python实战--基于Django的企业资源管理系统
  • 块体不锈钢上的光栅耦合表面等离子体共振的复现
  • 后端通用基础代码
  • 在嵌入式单片机开发中,通过校验和或者校验码来比对程序版本好有何优劣势
  • 【OLAP】trino安装和基本使用
  • 【完整源码+数据集+部署教程】无人机目标检测系统源码和数据集:改进yolo11-efficientViT
  • Linux网络服务(一)——计算机网络参考模型与子网划分
  • Linux bash核心介绍及目录命令
  • Android中使用RxJava实现网络请求与缓存策略
  • Git-2025-0818
  • 数据结构:查找表
  • 开源im即时通讯软件开发社交系统全解析:安全可控、功能全面的社交解决方案
  • 从零到GPT:Transformer如何引领大模型时代
  • Nextcloud 私有云部署:cpolar 内网穿透服务实现安全远程文件访问
  • 4G高负荷解决方案
  • 《红色脉-络:一部PLMN在中国的演进史诗 (1G-6G)》 第6篇 | 专题:核心网的第一次革命——从电路交换到“用户/控制面分离”
  • python-----机器学习中常用的数据预处理
  • 英特尔公司Darren Pulsipher 博士:以架构之力推动政府数字化转型
  • Apache RocketMQ,构建云原生统一消息引擎