Linux 中究竟有多少种内存叫法

2025-07-18 pv

操作系统要管理很多种资源,最重要的有两个:

  • 计算资源
  • 存储资源

这里暂时先将存储资源狭义地理解为内存资源

之前 文章🔗 文章讨过 Chromium 对于内存的精准管理,不过那是从应用程序的角度,比较宏观。

所以今天这篇文章,打算从更底层的角度出发,作为对比,观察操作系统对于内存的管理有何异同。

以 Linux 为例。不过基本思想大致相同。

1. Linux 内存分类

free 是一个 Linux 上常用的内存查看工具。

Terminal window
$ free -h
total used free shared buff/cache available
Mem: 15Gi 9.1Gi 4.4Gi 7.0Mi 1.9Gi 6.1Gi
Swap: 4.0Gi 1.3Gi 2.7Gi

每列字段的含义是:

列名含义
total物理内存/Swap 总量(RAM 总大小)
used已使用内存,包括应用、内核使用的,但不含 buffers/cache
free完全空闲的内存(没有被用)
shared多个进程共享的内存,通常是 tmpfs(如 /dev/shm
buff/cache缓冲区和缓存,用于加速文件访问,可被释放
available真正可用的内存:包含 free + 可回收缓存。这个值才是最值得参考的。

行的含义是:

  • Mem,物理内存
  • Swap,交换内存,位于磁盘

大部分概念都比较直白。

这里挑两个相对来说不容易理解的展开说说,Swap(交换分区) 和 Cache(缓存)。

Swap 是构建 Linux 虚拟内存的重要部分

虚拟内存是操作系统对物理内存所做的一层抽象,让程序误以为自己看到的是物理内存,其实不是。

比如,在 C 语言中打印出的指针地址,就是虚拟内存。对物理内存的访问,需要借助操作系统的地址翻译和映射

虚拟内存主要解决两个问题:安全和效率

安全指在访问物理内存前,操作系统可以做一些校验,对于越界访问,可以返回 Segmentation Fault 等错误。

效率是对于程序而言,看起来自己独占地拥有整片地址空间,对于操作系统,则可以更加灵活地管理内存。

一个经典的面试题:进程所能操作的内存空间,最大有多大?

其实是可以超过物理内存的

因为当物理内存不够时,Linux 会把一些暂时不用的内存页移动到硬盘的 Swap 分区。

当 Swap 区的内存又被需要时,会再次换回到物理内存中。

可能会对性能造成一定程度的影响,但对那些物理内存不足,又有很多活跃进程的机器,无疑是一种权宜之计。

Cache 是另一种优化技巧。

free 工具里的 Cache,是用于缓存磁盘文件内容的内存,称为 Page Cache(页缓存)。

对于空闲的物理内存,与其闲置,不如利用起来,毕竟内存的访问速度可比磁盘快得多。

2. Linux 内存优化

Linux 内存优化是一个内涵丰富的研究领域,涉及到的知识和工具繁多。

这里只简单罗列一些基础的优化手段,分三个层面:

  • 内核级别
  • 系统调优
  • 程序优化

2.1 内核级别

Linux 内核有针对内存的默认优化机制:

手段描述
Page Cache将文件内容缓存在内存,加快 I/O 速度
Lazy Allocation内存按需分配,减少浪费
Transparent Huge Pages(THP)自动将多个页合并为大页(HugePage),减少 TLB miss
KSM(Kernel SamePage Merging)多个进程中相同的内存页可合并为一个(如 KVM 虚拟化场景)
OOM Killer遇到内存耗尽时,自动杀死内存占用高的进程,防止系统崩溃

2.2 系统调优

系统级的调优,通常为管理员准备。几个常见的调整手段:

  1. swappiness 调整。可以控制系统使用 swap 的程度,范围 0-100,越低则 swap 使用越少。

    Terminal window
    $ sudo sysctl vm.swappiness=10
  2. drop_cache 清理缓存。可用来定期清除文件缓存。

    Terminal window
    $ echo 3 > /proc/sys/vm/drop_caches
  3. 开启 HugePage。对于数据库或高性能计算等对内存要求极高的场景。

    Terminal window
    # 查看支持的大页大小
    $ cat /proc/meminfo | grep Huge
    # 配置大页数量
    $ echo 512 > /proc/sys/vm/nr_hugepages
  4. 内存压缩(zswap / zram)。

    • zswap:将 swap 内容压缩后写入磁盘,提高空间利用效率
    • zram:直接在内存中创建压缩块设备作为 swap,适合低内存设备(如树莓派)
  5. cgroup 内存限制与隔离。通过 cgroup 限制每个进程的内存使用,提高管理精细度。

    Terminal window
    # 创建 cgroup 并限制内存
    $ echo 512M > /sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes

2.3 程序优化

这一块是普通开发者可以掌控的。

同样分三块:

  • 使用第三方内存分配器
  • 内存及时回收
  • 内存泄漏检测

常见的第三方内存分配器有 tcmallocjemalloc。具体的选型,依赖 Benchmark 和生产环境的测试结果。

内存及时回收更多是一种使用习惯,及时释放不用的内存、解除 mmap 文件映射,或者借助 malloc_trim() 等技巧。

内存泄露检测工具,常用的有:

  • Valgrind

  • Asan(Address Sanitizer)

  • Massif(内存使用分析)

3. Linux 内存工具

工具主要分两种,监控和分析。

工具用途
free / top / htop基础内存查看
vmstat查看 page in/out、缓存命中等
smem统计进程真实占用内存(PSS)
perf性能分析器,含内存访问事件
ps_mem.py查看各进程实际内存占用
sar历史内存负载趋势分析
slabtop查看 slab 分配器使用情况

如果想要获得更深刻的洞察,可以考虑采用 eBPF(Extended Berkeley Packet Filter,扩展伯克利数据包过滤器)。

4. 启发

Linux 里的内存优化机制,不仅是工程实践的问题,同样涉及理论研究的进步,比如内存分页、分段、HugePage 等。

这里推荐一本通俗的读物:《Operating Systems: Three Easy Pieces》,虽然是英文版,但是非常好读。

理论指导实践,实践丰富理论,两者结合,效果最佳。学习也一样。

工程上问题的解决通常是很务实的,遵循:

  • 遇到了什么问题
  • 有什么假设和推论
  • 验证
  • 找到可行解
  • 推广

这与产品开发的思路基本一致

5. 总结

之前文章,Chromium 与 RAM 的博弈🔗,更多谈及应用维度的内存优化。

这里是从更底层的操作系统层面。

可见,越是底层,作用的范围越大,能优化的手段也更多样。

同时也启示我们,学习要抓重点,抓关键,遵循第一性原理,拨开纷繁复杂的表象,抓住最核心、不变的东西, 就能起到四两拨千斤的效果。

(完)

参考

  1. eBPF - Introduction, Tutorials & Community Resources🔗
  2. Operating Systems: Three Easy Pieces🔗
在 GitHub 上编辑本页面

最后更新于: 2025-07-18T06:32:21+08:00