Linux 中究竟有多少种内存叫法
2025-07-18
操作系统要管理很多种资源,最重要的有两个:
- 计算资源
- 存储资源
这里暂时先将存储资源狭义地理解为内存资源。
之前 文章🔗 文章讨过 Chromium 对于内存的精准管理,不过那是从应用程序的角度,比较宏观。
所以今天这篇文章,打算从更底层的角度出发,作为对比,观察操作系统对于内存的管理有何异同。
以 Linux 为例。不过基本思想大致相同。
1. Linux 内存分类
free
是一个 Linux 上常用的内存查看工具。
$ free -h total used free shared buff/cache availableMem: 15Gi 9.1Gi 4.4Gi 7.0Mi 1.9Gi 6.1GiSwap: 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 系统调优
系统级的调优,通常为管理员准备。几个常见的调整手段:
-
swappiness 调整。可以控制系统使用 swap 的程度,范围 0-100,越低则 swap 使用越少。
Terminal window $ sudo sysctl vm.swappiness=10 -
drop_cache 清理缓存。可用来定期清除文件缓存。
Terminal window $ echo 3 > /proc/sys/vm/drop_caches -
开启 HugePage。对于数据库或高性能计算等对内存要求极高的场景。
Terminal window # 查看支持的大页大小$ cat /proc/meminfo | grep Huge# 配置大页数量$ echo 512 > /proc/sys/vm/nr_hugepages -
内存压缩(zswap / zram)。
- zswap:将 swap 内容压缩后写入磁盘,提高空间利用效率
- zram:直接在内存中创建压缩块设备作为 swap,适合低内存设备(如树莓派)
-
cgroup 内存限制与隔离。通过 cgroup 限制每个进程的内存使用,提高管理精细度。
Terminal window # 创建 cgroup 并限制内存$ echo 512M > /sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes
2.3 程序优化
这一块是普通开发者可以掌控的。
同样分三块:
- 使用第三方内存分配器
- 内存及时回收
- 内存泄漏检测
常见的第三方内存分配器有 tcmalloc
和 jemalloc
。具体的选型,依赖 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 的博弈🔗,更多谈及应用维度的内存优化。
这里是从更底层的操作系统层面。
可见,越是底层,作用的范围越大,能优化的手段也更多样。
同时也启示我们,学习要抓重点,抓关键,遵循第一性原理,拨开纷繁复杂的表象,抓住最核心、不变的东西, 就能起到四两拨千斤的效果。
(完)
参考
- 本文作者:Plantree
- 本文链接:https://plantree.me/blog/2025/linux-memory-101/
- 版权声明:所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
最后更新于: 2025-07-18T06:32:21+08:00