插件窝 干货文章 一文读懂Linux内存分配策略

一文读懂Linux内存分配策略

内存 分配 使用 进程 147    来源:    2025-05-14

Linux内存分配策略详解

内存管理基础概念

Linux内存管理是一个复杂的系统,主要涉及以下几个关键概念:

  1. 物理内存:实际存在的RAM芯片
  2. 虚拟内存:每个进程看到的独立地址空间
  3. 页面(Page):内存管理的基本单位,通常为4KB
  4. 页表(Page Table):虚拟地址到物理地址的映射表

主要内存分配策略

1. Buddy System (伙伴系统)

作用:管理物理内存的分配和释放

特点: - 将内存划分为不同大小的块(2^0, 2^1,..., 2^MAX_ORDER页) - 分配时寻找最合适大小的块 - 释放时会合并相邻的空闲块

优点: - 减少内存碎片 - 分配效率高(O(1)时间复杂度)

2. Slab分配器

作用:管理内核对象的内存分配

特点: - 为常用内核对象(如task_struct)创建缓存 - 对象使用后不立即释放,而是放回缓存 - 分为专用slab和通用slab

优点: - 减少内存分配/释放开销 - 提高缓存命中率

3. 页面回收策略

Linux使用多种策略回收不再使用的内存页面:

a. 页面缓存(Page Cache)

  • 文件系统缓存
  • 可回收优先级最高

b. 匿名页面(Anonymous Pages)

  • 进程堆栈、堆等内存
  • 通过交换分区(Swap)回收

c. KSM (Kernel Samepage Merging)

  • 合并相同内容的页面
  • 主要用于虚拟机环境

4. OOM Killer (内存耗尽杀手)

触发条件: - 系统内存严重不足 - 无法通过常规回收释放足够内存

行为: - 根据评分选择并终止进程 - 评分因素包括内存占用、运行时间、进程优先级等

内存分配API

用户空间分配

  1. malloc/free:C标准库函数

    • 通常使用brk/sbrk或mmap实现
    • glibc的ptmalloc是最常见实现
  2. mmap/munmap:内存映射

    • 可用于文件映射或匿名映射
    • 大内存分配通常使用mmap

内核空间分配

  1. kmalloc/kfree:小内存分配

    • 基于slab分配器
    • 分配物理连续的内存
  2. vmalloc/vfree:大内存分配

    • 分配虚拟连续但物理不一定连续的内存
    • 适用于大块内存需求
  3. alloc_pages:页面级分配

    • 直接使用伙伴系统
    • 适用于需要精确控制页面的场景

内存分配调优参数

Linux提供了多种参数来调整内存分配行为:

  1. vm.swappiness (0-100)

    • 控制交换匿名页面的倾向
    • 值越高,内核越倾向于使用swap
  2. vm.overcommit_memory (0,1,2)

    • 控制内存过量分配策略
    • 0: 启发式过量分配
    • 1: 总是过量分配
    • 2: 禁止过量分配
  3. vm.dirty_ratio/vm.dirty_background_ratio

    • 控制脏页写回磁盘的阈值
  4. vm.min_free_kbytes

    • 系统保留的最小空闲内存

内存分配问题排查工具

  1. free:查看系统内存使用概况

    free -h
    
  2. vmstat:查看虚拟内存统计

    vmstat 1
    
  3. top/htop:查看进程内存使用

  4. pmap:查看进程内存映射

    pmap -x <pid>
    
  5. slabtop:查看slab分配情况

    slabtop
    
  6. /proc/meminfo:详细内存信息

    cat /proc/meminfo
    

实际应用建议

  1. 对于内存密集型应用

    • 考虑使用大页(Huge Pages)减少TLB压力
    • 调整swappiness降低交换倾向
  2. 对于延迟敏感应用

    • 使用mlock锁定关键内存防止被换出
    • 考虑使用CMA(连续内存分配器)
  3. 对于内存碎片问题

    • 定期重启长期运行的服务
    • 考虑使用内存碎片整理(需要内核支持)
  4. 对于OOM问题

    • 调整oom_score_adj保护关键进程
    • 增加swap空间作为缓冲

通过理解这些内存分配策略和工具,您可以更有效地管理和优化Linux系统的内存使用。