插件窝 干货文章 一文剖析 Linux 内核的内存管理

一文剖析 Linux 内核的内存管理

内存 回收 分配 系统 826    来源:    2025-05-14

Linux 内核内存管理深度剖析

1. 内存管理概述

Linux 内核的内存管理系统是操作系统最复杂的子系统之一,负责高效地管理物理内存和虚拟内存。其主要功能包括:

  • 物理内存管理
  • 虚拟地址空间管理
  • 内存分配与释放
  • 内存映射
  • 页面缓存
  • 交换空间管理
  • 内存回收

2. 物理内存管理

2.1 内存模型

Linux 支持三种内存模型:

  1. 平坦内存模型(Flat Memory Model):最简单的模型,所有内存被视为连续空间
  2. 不连续内存模型(Discontiguous Memory Model):用于有物理内存空洞的系统
  3. 稀疏内存模型(Sparse Memory Model):现代系统常用,支持热插拔内存

2.2 内存区域(Zone)

Linux 将物理内存划分为几个区域(zone):

  • ZONE_DMA:用于DMA操作的内存(<16MB)
  • ZONE_DMA32:用于32位设备DMA操作的内存(<4GB)
  • ZONE_NORMAL:正常映射的内存
  • ZONE_HIGHMEM:高端内存(32位系统上>896MB)
  • ZONE_MOVABLE:可移动内存区域(用于内存热插拔)

2.3 伙伴系统(Buddy System)

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

  • 将空闲页面组织为11个链表,分别对应1,2,4,...,1024个连续页面块
  • 分配时查找满足要求的最小块,如果找不到则分裂更大的块
  • 释放时检查相邻块是否是"伙伴"(大小相同且物理连续),如果是则合并
struct zone {
    ...
    struct free_area free_area[MAX_ORDER];
    ...
};

struct free_area {
    struct list_head free_list[MIGRATE_TYPES];
    unsigned long nr_free;
};

3. 虚拟内存管理

3.1 地址空间布局

32位系统典型布局:

0x00000000 - 0xC0000000 : 用户空间(3GB)
0xC0000000 - 0xFFFFFFFF : 内核空间(1GB)

64位系统典型布局:

0x0000000000000000 - 0x00007fffffffffff : 用户空间(128TB)
0xffff800000000000 - 0xffffffffffffffff : 内核空间(128TB)

3.2 页表管理

Linux 使用四级页表结构(64位系统): 1. PGD (Page Global Directory) 2. P4D (Page 4th Level Directory) 3. PUD (Page Upper Directory) 4. PMD (Page Middle Directory) 5. PTE (Page Table Entry)

3.3 内存映射

内存映射通过mmap系统调用实现,有两种主要类型: - 文件映射:将文件内容映射到进程地址空间 - 匿名映射:分配不与文件关联的内存

4. 内存分配机制

4.1 页分配器(Page Allocator)

基于伙伴系统,提供以下接口: - alloc_pages:分配2^n个连续物理页 - __get_free_pages:分配并返回虚拟地址 - get_zeroed_page:分配清零的页

4.2 SLAB分配器

用于管理内核中小对象的分配,解决内部碎片问题。有三种实现: 1. SLAB:经典实现 2. SLUB:简化版,现代系统默认 3. SLOB:用于内存受限的系统

struct kmem_cache {
    struct array_cache *cpu_cache;  // 每CPU缓存
    unsigned int size;              // 对象大小
    unsigned int objsize;           // 实际对象大小
    unsigned int offset;            // 空闲指针偏移
    struct kmem_cache_node *node[MAX_NUMNODES];  // 节点缓存
    ...
};

4.3 vmalloc

分配虚拟地址连续但物理地址不一定连续的内存,用于大块内存分配。

5. 内存回收机制

5.1 页面缓存(Page Cache)

Linux 使用页面缓存来缓存文件数据,主要特点: - 使用radix树高效索引 - 采用写回(writeback)策略 - 支持预读(readahead)

5.2 交换(Swap)

当物理内存不足时,将不常用的页面换出到交换空间: - 使用交换区(swap area)存储换出页面 - 每个交换区由多个4K的页槽(page slot)组成 - 使用交换缓存(swap cache)管理换入换出

5.3 内存回收策略

  1. 直接回收:当分配失败时同步回收
  2. 后台回收(kswapd):内核线程定期回收
  3. OOM Killer:极端情况下终止进程释放内存

回收算法基于LRU(最近最少使用)改进,分为: - 活跃链表(active list) - 非活跃链表(inactive list)

6. 高级特性

6.1 透明大页(THP)

自动将普通页(4K)合并为大页(2M),减少TLB失效,提高性能。

6.2 内存压缩(zswap/zsmalloc)

在内存回收前尝试压缩页面,减少交换I/O。

6.3 内存热插拔

支持运行时添加或移除内存模块。

6.4 Control Groups内存控制

通过cgroups限制和监控进程组的内存使用。

7. 性能调优参数

重要/proc/sys/vm参数: - swappiness:交换倾向(0-100) - vfs_cache_pressure:回收inode/dentry缓存倾向 - dirty_ratio/dirty_background_ratio:脏页比例阈值 - min_free_kbytes:最小保留内存 - zone_reclaim_mode:内存区域回收策略

8. 内存问题诊断工具

  1. free:查看内存使用概况
  2. vmstat:监控内存、交换、I/O等
  3. top/htop:进程内存使用
  4. pmap:进程地址空间分析
  5. slabtop:SLAB分配器使用情况
  6. numastat:NUMA内存统计
  7. perf:内存相关性能分析

9. 总结

Linux 内存管理系统是一个高度优化的复杂子系统,它通过多种机制和算法在以下方面取得平衡: - 性能(减少碎片、提高缓存命中率) - 可靠性(防止内存耗尽) - 灵活性(支持多种硬件架构) - 可扩展性(从小型嵌入式系统到大型服务器)

理解Linux内存管理机制对于系统调优、性能分析和问题诊断至关重要。随着硬件发展和新需求出现,Linux内存管理仍在不断演进,如对非易失性内存(NVM)的支持、更智能的回收算法等。