linux 内核内存管理概述

Linux 内核内存管理详解

Linux 内核的内存管理是一个复杂而精妙的系统,负责管理物理内存和虚拟内存,为进程提供内存分配服务。以下是 Linux 内存管理的主要组成部分和工作原理的详细解析。

1. 内存管理架构概述

Linux 内存管理系统采用分层设计,主要包含以下几个层次:

  • 硬件抽象层:处理特定架构的内存管理单元(MMU)细节

  • 物理内存管理:处理物理页帧的分配和释放

  • 虚拟内存管理:提供进程地址空间抽象

  • 内存分配器:提供kmalloc、vmalloc等接口

  • 用户空间接口:通过brk、mmap等系统调用提供服务

2. 物理内存管理

2.1 物理内存组织

Linux 使用节点(Node)、区域(Zone)、页(Page)的三级结构管理物理内存:

  1. 节点(Node):对应 NUMA 系统中的节点,每个节点有自己的内存

  2. 区域(Zone):每个节点分为多个区域,常见的有:

    • ZONE_DMA:用于DMA操作的内存

    • ZONE_NORMAL:普通映射的内存

    • ZONE_HIGHMEM:高端内存(32位系统)

  3. 页(Page):物理内存被划分为页帧(page frame),通常是4KB大小

2.2 伙伴系统(Buddy System)

Linux 使用伙伴系统管理物理页帧的分配和释放:

  • 将空闲页帧组织成11个链表(0-10),每个链表包含2^n大小的页块

  • 分配时从合适大小的链表获取,如果没有则分裂更大的块

  • 释放时会尝试合并"伙伴"块(地址相邻且大小相同的空闲块)

// 内核中的伙伴系统主要接口
struct page *alloc_pages(gfp_t gfp_mask, unsigned int order);
void free_pages(unsigned long addr, unsigned int order);

2.3 每CPU页框缓存

为减少伙伴系统的锁竞争,内核为每个CPU维护了:

  • 热缓存:页表可能存在于CPU缓存中

  • 冷缓存:页表不在CPU缓存中

3. 虚拟内存管理

3.1 地址空间布局

Linux 进程的虚拟地址空间通常布局如下:

0x00000000-0x08048000: 保留区域
0x08048000-0x...: 代码段(text)
0x...-0x...: 数据段(data)
0x...-0x...: 堆(heap,通过brk增长)
0x...-0x...: 共享库映射
0x...-0x...: 栈(stack,向下增长)
0xC0000000-0xFFFFFFFF: 内核空间(3GB/1GB分界)

3.2 页表管理

Linux 使用多级页表将虚拟地址转换为物理地址:

  • x86_32: 两级页表(PGD, PTE)

  • x86_64: 四级页表(PGD, PUD, PMD, PTE)

  • ARM: 三级页表

转换过程由 MMU 硬件完成,内核负责维护页表内容。

3.3 内存映射

Linux 通过 mm_struct 结构管理进程地址空间,vm_area_struct 描述虚拟内存区域(VMA):

struct mm_struct {
    struct vm_area_struct *mmap;  // VMA链表
    pgd_t *pgd;                   // 页全局目录
    // ...
};

struct vm_area_struct {
    unsigned long vm_start;     // 起始地址
    unsigned long vm_end;       // 结束地址
    vm_flags_t vm_flags;        // 权限标志
    struct file *vm_file;       // 映射的文件(如果有)
    // ...
};

4. 内核内存分配器

4.1 SLAB分配器

用于内核对象的高效分配,特点:

  • 缓存常用对象类型(如task_struct)

  • 避免频繁初始化和释放的开销

  • 减少内存碎片

主要接口:

kmem_cache_t *kmem_cache_create(...);
void *kmem_cache_alloc(kmem_cache_t *, gfp_t flags);
void kmem_cache_free(kmem_cache_t *, void *);

4.2 kmalloc/vmalloc

  • kmalloc:分配连续的物理内存,适用于小内存分配

    void *kmalloc(size_t size, gfp_t flags);
  • vmalloc:分配连续的虚拟内存,物理内存可以不连续

    void *vmalloc(unsigned long size);

5. 内存回收机制

5.1 页面缓存(Page Cache)

Linux 使用空闲内存作为文件缓存,通过以下机制回收:

  • LRU列表:维护活跃和非活跃页面

  • 页面回收:当内存不足时回收非活跃页面

5.2 交换(Swap)

将不常用的内存页换出到磁盘交换分区:

  • 使用交换缓存避免重复IO

  • 交换优先级:匿名页 > 非活跃文件页

5.3 OOM Killer

当系统内存严重不足时,选择并终止占用内存多的进程。

6. 内存管理相关系统调用

  • brk/sbrk:调整堆的大小

  • mmap/munmap:内存映射/取消映射

  • mlock/munlock:锁定/解锁内存

  • madvise:提供内存使用建议

  • shmget/shmat:共享内存操作

7. 高级特性

7.1 透明大页(THP)

自动将小页合并为大页(2MB或1GB),减少TLB缺失。

7.2 内存压缩(zswap/zram)

在内存不足时压缩页面而非交换到磁盘。

7.3 控制组(cgroups)内存控制

限制和控制进程组的内存使用。

8. 性能调优参数

  • /proc/sys/vm/swappiness:控制交换倾向(0-100)

  • /proc/sys/vm/dirty_ratio:控制脏页比例

  • /proc/sys/vm/overcommit_memory:内存过量使用策略

  • /proc/sys/vm/zone_reclaim_mode:NUMA内存回收模式

总结

Linux 内存管理系统通过精妙的分层设计和多种算法,实现了高效的内存管理。理解其工作原理对于系统调优、性能分析和内核开发都至关重要。随着硬件发展和新需求出现,Linux 内存管理仍在不断演进,如近年来对非易失性内存的支持等新特性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值