Linux 系统的”内存够不够用”从来不是只看物理条多大那么简单——Swap(交换分区/文件)、虚拟地址映射、swappiness 倾向值、zram 压缩内存共同决定了系统在内存吃紧时究竟是被 OOM Killer 直接砍进程,还是悄悄扛过尖峰后再恢复。本文从 free 命令的字面解读出发,逐层讲清 Linux 内存组成的物理/虚拟/Swap 三块关系、Swap 的几种实现方式、swappiness 与 /proc/sys/vm/ 参数调优、zram 压缩内存的取舍,最后落到 OOM 排查与 vmstat/sar 监控套路。文末附常用监控命令清单,方便日常排查时直接抄。
\n
一、为什么必须理解 Linux 内存管理
\n
很多人第一次登录 Linux 机器,看到 free -h 输出里 available 只有几百 MB,第一反应是”内存不够要加条”。其实 Linux 的可用内存计算远比 Windows 直观——它会把空闲内存主动拿去做 Page Cache、Buff/Cache、Slab 等可回收用途,真正可分配的额度要看 available,而不是 free。如果一看到 available 偏低就匆忙扩容,就忽略了 Swap、回收策略、内核参数这些更廉价的优化手段。要玩好「Linux 内存管理」,先得理解物理内存、虚拟内存、Swap 三者的分工。
\n
二、Linux 内存组成的三个层次
\n
物理内存(Physical RAM)即插在主板上的条;虚拟内存是进程视角的连续地址空间,由 CPU 的 MMU 配合内核页表映射到物理页帧;Swap 则是物理页帧吃紧时,内核把若干页帧换出到磁盘上的”溢出仓库”。
\n
2.1 物理内存与页帧
\n
内核以 4KB(默认)页帧为单位管理物理内存,每页都有 struct page 维护引用计数、LRU 链、反向映射。当进程 malloc 拿到虚拟地址后,第一次访问触发缺页异常,内核才真正分配物理页帧并建立映射,这种”按需分页”是 Linux 内存高效复用的基础。理解这一点对排查「内存泄漏排查」很关键——进程虚拟尺寸(VSZ)很大不代表物理占用大,要看 RSS(驻留集)和 page fault 频率。
\n
2.2 Swap 的两种形态
\n
Swap 既可以是独立的磁盘分区(/dev/sda2,性能好),也可以是普通文件(/swapfile,灵活)。两者在内核看来都是「若干 4KB 页槽位的连续地址空间」,底层都是 swap_map 管理。换出策略沿用 LRU 与第二次机会算法,冷页优先被踢到磁盘——这也是为什么大文件读写后 available 会先掉下来,等缓存回收又会回升。
\n
三、free/top 命令深度解读
\n
3.1 free 的四列含义
$ free -h\n total used free shared buff/cache available\nMem: 7.7G 1.9G 268M 132M 5.6G 5.3G\nSwap: 2.0G 124M 1.9G
\n
重点看 available,不是 free。available = free + 可回收的 buff/cache 一部分,它是内核承诺能立即分给新进程的内存。 buff/cache 高不代表浪费,IO 密集场景它就是写回磁盘前的缓冲,回收成本极低。
\n
3.2 top 与 htop 实战
top 里 RES(驻留集)是进程实际占用的物理页大小,VIRT 是虚拟地址空间大小(含 mmap 的库与未触发的页),%MEM 按 RES / 总物理内存计算。htop 比 top 更直观,可以按内存/IO/线程分组,F2 进入 setup 还能加仪表盘。要判断谁在持续吃内存,看 RES 是否单调上升、能否稳定到某个值——后者是缓存增长,前者才可能是「swap 调优」要处理的真实压力。
\n
四、Swap 分区的几种实现方式
\n
4.1 传统 Swap 分区
传统方案是分一个独立分区(建议 ≥ 物理内存的 1~2 倍,但超过 8GB 后收益递减)。创建流程:fdisk 建分区 → mkswap 格式化 → swapon 启用 → 写入 /etc/fstab 开机自动挂载。完整的磁盘操作可参考本站 Linux 磁盘分区、格式化与挂载实战。如果你的机器更关心快速上线、临时扩容,下面的 swapfile 更省事。
\n
4.2 Swapfile(推荐云服务器)
$ fallocate -l 4G /swapfile\n$ chmod 600 /swapfile\n$ mkswap /swapfile\n$ swapon /swapfile\n$ echo '/swapfile none swap sw 0 0' >> /etc/fstab
Swapfile 的好处是不动分区表、可随时 swapoff /swapfile 回退,缺点是大 IO 密集场景会跟数据盘抢 IO,适合内存吃紧但磁盘是 SSD 的中小型实例。
\n
4.3 zram 压缩内存
zram 是把压缩块放回 RAM 当 Swap 用,相当于「用 CPU 换 IO」,特别适合无盘或低内存场景(容器、笔记本、嵌入式)。Ubuntu/Debian 默认在 /etc/init.d/zram-config 或 systemd zramswap.service 启用,配额通常为物理内存的 25%~50%。
\n
五、swappiness 与内核参数调优
\n
5.1 swappiness 到底是什么
swappiness 是 0~100 的倾向值:值越大,内核越”激进”地把页换出到 Swap;值越小,越倾向于回收 Page Cache 而非换出匿名页。CentOS 默认 60,Ubuntu 自 22.04 起默认 60,部分桌面发行版用 10。
$ sysctl vm.swappiness # 查看当前值\n$ sysctl vm.swappiness=10 # 临时改为 10\n$ echo 'vm.swappiness=10' >> /etc/sysctl.d/99-swap.conf # 永久生效
5.2 经验取值
数据库/延迟敏感型业务(MySQL、Redis、Elasticsearch)建议 1~10,宁可 OOM 也要避免 IO 抖动;通用 Web/中小实例 10~30 比较平衡;纯冷备/批处理可以回到 60 以上让 Swap 更主动。
其他常调参数:vm.dirty_ratio(脏页占内存比,超出刷盘)、vm.vfs_cache_pressure(倾向回收 dentry/inode 缓存)、vm.min_free_kbytes(保留给紧急分配的最小空闲)。想理解这些参数背后更广义的Linux 系统优化思路,可以结合 Linux 进程管理与系统监控 一文,从进程级视角反推内核行为。
\n
六、zram 压缩内存:低内存机器的救星
zram 的原理是把 Swap 放在 RAM 里但用 LZ4/ZSTD 实时压缩,等于在不动硬件的前提下”扩容”内存。它在内存碎片化时代价低、IO 极低(只是 CPU 多做一次解压),启动后直接挂在 /dev/zram0 上,用 swapon -p 100 /dev/zram0 还能让它比磁盘 Swap 更优先被使用。代价是 CPU 占用上升 5%~15%,压缩比通常 2:1~3:1,所以 4GB 物理内存配 4GB zram,实际可用 ≈ 8–10GB。
七、内存泄漏与 OOM 排查实战
\n
当 dmesg 里反复刷 Out of memory: Killed process 时,先看物理内存和 Swap 是否真的耗尽(free -h + vmstat 1 5),再缩小嫌疑人范围:
ps aux --sort=-%mem | head找出 RES 最大的几个进程。cat /proc/<pid>/smaps | grep -i Rss看进程的内存段分布,定位是堆、栈、还是 mmap 区在涨。valgrind --tool=memcheck或heaptrack跟踪 C/C++ 程序分配峰值;JVM 加-XX:+HeapDumpOnOutOfMemoryError让 OOM 时落 dump。- 内核日志太多被冲走,可用
dmesg -T | grep -i 'killed'过滤,配合 Linux 日志系统实战 一文里讲的 journalctl 永久保存日志。
八、常用监控命令清单
free -h/vmstat 1 5:看整体内存与 Swap 进出。top / htop:进程维度,常驻内存、CPU 占用的实时榜单。sar -r 1 5:历史内存使用率曲线(需 sysstat 包)。pidstat -r 1:看每个进程每秒的页面错误与回收。slabtop:内核 slab 分配器占用,排查缓存泄漏。numastat -m:NUMA 机器内存分布,定位跨节点访问瓶颈。
把这条命令清单与定时任务结合(例如每 5 分钟跑一次 sar -r,落日志到指定目录),就能搭一个轻量级Linux 系统监控。具体怎么配周期任务,Linux 定时任务与 systemd timer 实战 里给出了可直接抄的命令行。
结语
Linux 内存管理不是”加条内存”这么简单。理清物理/虚拟/Swap 关系、调对 swappiness、按场景选 zram 或 swapfile、配合 vmstat/sar 做长期监控——这套组合拳下来,绝大多数”内存不够”的吐槽都能在没有硬件升级预算的前提下缓解。下一次见到 available 告警,先别急着下单买内存,按本文顺序排查一遍。










暂无评论内容