- Linux 会将所有可用 RAM 用于缓存和页面缓存,因此可用内存少并不一定意味着存在问题。
- 交换空间、zram/zswap 和 vm.swappiness 的适当设置相结合,可以平衡性能和稳定性。
- cgroup v2、systemd-oomd 和 earlyoom 或 nohang 等工具可以对内存压力和 OOM 事件进行精细控制。
- 使用 free、vmstat、htop、sar 或 Glances 进行监控是发现瓶颈和优化内存管理的关键。

如果你负责系统管理、容器操作或生产服务器维护,那么深入理解 Linux 内存管理已不再是可选项。它决定了服务器能否轻松应对负载高峰,还是会举步维艰、进入崩溃模式,甚至在最糟糕的时刻触发令人头疼的 OOM killer。
Linux 的设计目标是尽可能高效地利用内存:它会缓存文件、压缩页面、将数据移至交换空间,并根据非常精确的策略对进程进行优先级排序。从表面上看,它似乎“占用大量内存”或“总是没有可用内存”,但实际上,它是为了实现最佳性能和稳定性。接下来,我们将一步一步地用一些通俗易懂的方式解释这一切是如何运作的,以及如何进行高级的微调。
Linux内存的基本概念和误区

在随意修改内核参数或挂载 zram 之前,最好先对内存类型、架构以及系统如何看待 RAM有一些清晰的了解。
计算机可处理的最大物理内存量取决于操作系统和处理器架构。32 位系统通常限制为 4 GB 内存,而 64 位系统可以轻松处理数十或数百 GB 内存(理论上可以处理更多,但实际限制由硬件决定)。
在 Linux 系统中,所有内存都以虚拟内存的形式进行管理,包括物理内存和交换空间。物理内存只能通过添加物理模块来扩展,而虚拟内存则可以通过磁盘(分区或交换文件)以及 zram 或 zswap 等高级机制进行扩展。
La 物理内存(RAM) 它是速度快但成本高的资源:进程、库、文件缓存、I/O 缓冲区、共享内存等等都加载到内存中。Linux 的理念非常明确:如果有空闲内存,最好将其用作缓存以加快访问速度,而不是让它空着。这就是为什么在诸如 之类的工具中很少看到“可用”内存的原因。 free 这并不意味着你遇到了问题。
磁盘内存(持久存储)速度要慢得多。RAM 的响应速度以纳秒计,而即使是 SSD 的响应速度也以微秒或毫秒计。因此,系统会尽量将常用数据保存在 RAM 中,只有在绝对必要时才会访问磁盘:例如加载可执行文件、读取冷数据或交换页面。
虚拟内存、页面和内核内部结构
虚拟内存是Linux为每个进程提供独立、隔离且受保护的地址空间的机制。硬件和内核通过称为页表的结构将虚拟地址转换为物理地址。
管理内存的最小单位是页,通常为 4 KB。整个虚拟内存系统围绕页展开:页被分配、释放、交换、缓存,并被标记为不同的权限(只读、执行等)。
页表是由内核维护的层级结构。它存储每个进程的每个虚拟页的实际物理页的位置(如果存在)、权限和当前状态。这种转换机制使得进程之间可以隔离,页面可以在进程间共享,文件也可以直接映射到内存中。
当进程访问一个有效的地址,但该页面尚未准备好访问时,就会发生缺页错误。缺页错误可能很轻(页面在内存中,但状态需要更新),也可能很重(页面在磁盘、交换空间或文件中,必须从内存中调出)。如果缺页错误频繁发生,系统会因为花费太多时间从磁盘读取数据而变慢。
页面缓存是由内核维护的文件页面缓存。它存储文件和目录的数据及元数据,以减少磁盘访问。这也是Linux“看起来”会占用所有内存的原因之一:实际上,它利用了应用程序未主动使用的内存来加速磁盘访问。
内存类型:文件支持型内存、匿名内存,以及它们与交换空间的关系
在Linux系统中,通常区分文件内存和匿名内存。两者都驻留在RAM中,但它们的来源和可能的磁盘备份方式不同。
电话 文件内存 它由系统文件备份:可执行二进制文件、共享库、映射数据。 mmap 从文件等位置读取数据。如果需要空间,可以丢弃该内存并从原始文件重新加载。
La 匿名记忆 它包含了进程保留的、不与文件绑定的所有东西:动态堆、栈、私有区域等等。 MAP_ANONYMOUS以及在执行操作时通过版权保护复制的区域 fork()该内存仅存在于 RAM 中(如果移动则存在于交换空间中),并且其唯一可能的备份也正是该交换空间。
当内核需要释放内存时,它会首先尝试释放可以重新组装的页面:通常是来自页面缓存或文件支持区域的页面。只有当没有更多空间或内存压力非常高时,它才会开始将匿名内存推入交换空间,虽然这样做开销更大,但可以让系统得到喘息之机。
内存压力、频繁刷新和 OOM 杀手
当空闲页数低于某些内部阈值时,就会出现内存压力。此时,内核将被迫不断释放内存:清除缓存、将脏页写入磁盘、驱逐不常用的页面等等。
内存压力过高会产生非常明显的症状:Web 服务延迟高、图形界面运行缓慢、远程会话(SSH、VNC、RDP)响应延迟、鼠标操作卡顿、窗口反应需要几秒钟等等。此时,系统更关注的是生存而不是执行有用的工作。
当内存不足以容纳进程不断使用的页面时,就会发生页面抖动。内核会开始持续交换页面:它驱逐一个页面插入另一个页面,但随后又立即需要刚刚驱逐的页面。这会导致页面错误和磁盘访问的循环,从而降低性能。
启用交换空间后,抖动意味着匿名页面会在内存和交换空间之间来回移动,导致磁盘空间饱和。禁用交换空间后,问题会转移到文件页面:这些页面会被反复丢弃并从文件系统中重新加载,这也会导致机器几乎无法使用。
如果内核仍然无法获取可用内存,则会发生以下情况: 内存不足(OOM)机制当所有可以丢弃、压缩或交换的数据都用尽后,内核会计算每个进程的得分(oom_score并决定牺牲哪一个。这个过程由……完成。 OOM 杀手 释放大量内存,避免系统彻底崩溃。
交换:它是什么,应该投入多少,以及为什么它并非“魔鬼”
交换内存名声不佳,部分原因是由于过时的建议和过于简单化的说法,例如“如果你的内存很大,就不需要交换空间”。实际上,即使在内存充足的系统中,交换空间也是 Linux 内存设计的关键组成部分。
交换空间是磁盘上的一个区域(分区或文件),内核用它来存储不活跃的内存页。这样可以释放内存,供真正需要的进程使用。它本身并不是虚拟内存,而是实现虚拟内存的机制之一。
如果没有交换空间,当内存压力增加时,匿名页面将无处可去。内核仍然可以依赖缓存和文件支持的页面,但一旦匿名内存使用量达到临界值,它实际上会被迫更早地触发内存溢出杀手(OOM killer)。从技术上讲,Linux 可以在没有交换空间的情况下运行,但实际上,在大多数情况下,这是一种不必要的风险。
在确定交换空间的大小时,并没有统一的标准,但根据机器的功能,有一些相当合理的现代标准:
- 没有休眠状态的服务器即使拥有大量内存,4-8 GB 的交换空间通常也足以作为缓冲。对于内存密集型服务(例如数据库、虚拟化),您可以将其增加到内存的 1,5 倍,但首要任务应该是增加物理内存。
- 不休眠的桌面对于 16 GB 或以上的 RAM,2-4 GB 的交换空间作为安全保障就绰绰有余了。
- 具备休眠功能的设备交换空间必须等于或略大于 RAM,因为系统在休眠时会将内存中的所有内容转储到交换空间中。
创建交换空间非常灵活。您可以使用专用分区或交换文件。如果您的磁盘已经分区,或者您想在不重新配置整个系统的情况下调整交换空间的大小,那么交换文件是理想的选择。
内存指标:free、vmstat、ps、RSS、PSS 等
如果您不了解每一列的含义,传统的 Linux 内存管理工具可能会导致误解。 free -h 这是最简单直观地查看总内存、已用内存、可用内存、缓存和交换空间的方法。
在出口处 free 关键是要查看扣除缓冲区和缓存的那一行,因为该列指示了…… 进程实际占用的内存还不包括内核用作缓存的内容,内核可以根据需要快速释放这些内容。
连接器 vmstat -s -S M 您可以获得更详细的摘要:总内存、已用内存、可用内存、活动内存、空闲内存、交换缓存等。您还可以查阅 /proc/meminfo 虽然输出结果比较枯燥,不太方便用户查看,但可以详细查看每个指标。
为了找出哪些进程对内存占用影响最大, ps aux 显示列,例如 VSZ (如果进程加载所有内容,则可以使用的总虚拟内存) RSS (驻留内存集大小,即当前实际占用在 RAM 中的内存)。注意:RSS 也包含共享库内存,如果多个进程使用共享库内存,则会被多次计算。
在这里发挥作用 PSS(比例集大小)它将共享库的成本分摊到使用这些库的进程之间。为了方便地获取 PSS,可以使用一些工具,例如 smem这对于查看哪些应用程序真正“占用大量数据”非常有用,而不会因为共享库而扭曲数据。
内存碎片、栈、堆和 ulimit
内存管理的另一个不太明显的方面是碎片化。我们可以讨论内部碎片化(当以 4、8 或 16 字节的倍数分配整数块时,会留下无用的部分)和外部碎片化(当存在空闲内存,但被分割成小块,从而阻止使用大的连续分配时)。
在像 Redis 这样的应用程序中,您有时会发现系统(RSS)报告的内存与应用程序本身认为有用的内存之间存在差异(used_memory这种距离通常主要是由于 外部碎片系统将某些空间计为已占用,但进程实际上并未使用这些空间。
过程记忆在概念上分为以下几部分: 栈和堆栈用于局部变量和函数调用,而堆用于动态分配。 malloc() 类似地,当数据结构的大小超过栈的容纳能力时,它们会被从堆中取出,并使用指针进行管理。
每个进程的最大堆栈大小可以通过以下方式调整: ulimit -a 以及系统配置。降低此值会限制大型局部变量的数量,而增加此值则允许使用更多变量或进行更深层次的递归。调整此参数有助于更好地控制内存使用并减少某些类型的内存碎片,但这并非万全之策。
高级监控和诊断:top、htop、vmstat、sar 等
要查找占用内存的进程,您可以从以下方面开始: top 如果你想要更人性化的功能,那么…… htop后者显示 CPU、内存和交换空间使用情况条,并允许对进程进行交互式排序和筛选。
在 Debian 及其衍生发行版中, 安装 htop 同 sudo apt install htop在 AlmaLinux 和其他类似 Red Hat 的系统中, sudo dnf install htop进入后,您可以按内存排序、搜索特定进程,并直接从界面终止问题任务。
为了进行更深入的分析和批量处理, vmstat 5 它定期提供有关进程、内存、分页、块 I/O、中断和 CPU 调度的信息。它非常适合用来观察内存压力随时间的变化情况。
该套件 系统状态 它包含以下工具: sar它允许您记录和分析内存和其他资源的使用情况。例如, sar -r 1 5 它每秒显示五次内存和交换空间使用情况。在 Debian 系统中,它是通过以下方式安装的: sudo apt install sysstat在 AlmaLinux 中 sudo dnf install sysstat.
如果您需要进行深度内核级调试, bpftrace 这是一个基于 eBPF 的强大工具。它允许您对系统调用进行插桩、观察内存访问并检测瓶颈,而无需重新编译或重启。它通常随程序一起安装。 sudo apt install bpftrace 在类似 Debian 的系统上。
实用内存管理:交换空间、可交换性以及缓存清理
许多服务器上的一项基本任务是检查 当前交换状态。 同 swapon --show 您会看到一份活动交换设备和文件的列表,其中包含它们的大小、类型和优先级。如果您需要动态添加交换空间,可以创建一个文件。 fallocate获得安全许可 chmod 600用以下格式格式化 mkswap 并用 swapon要使其永久生效,只需将相应的条目添加到 /etc/fstab.
参数 vm.swappiness 此参数控制内核优先使用交换空间而非继续填充 RAM 的程度。取值范围为 0 到 100。较低的值(10-20)会使系统尽量避免使用交换空间,除非绝对必要;而较高的值(60 或更高)则会促使系统更频繁地将页面移动到交换空间,以保持 RAM 的可用空间。
对于磁盘速度慢或数据库庞大的服务器来说,这通常很有意义。 降低交换频率例如,到 10 或 20,用 sudo sysctl vm.swappiness=10对于配备快速 ZRAM 或 SSD 的台式机,30-60 等中间值可以在延迟和内存利用率之间提供良好的平衡。
在记忆尚可的情况下,有时需要强制…… 缓存释放 同 sudo sync && sudo sysctl -w vm.drop_caches=3这会清空大部分页面缓存和目录项。偶尔在测试或释放资源非常有限的系统内存时很有用,但不应经常使用,因为这样也会失去缓存带来的性能提升。
高级控制工具:用户空间中的 cgroup v2、memory.pressure 和 OOM
在采用 systemd 和cgroup v2 的现代系统中,可以通过进程组对内存管理进行精细调整。cgroup v2将任务组织成层级结构,并在组级别(而非单个进程级别)应用资源限制和优先级(CPU、内存、I/O)。
在内存层次结构中,诸如以下参数: memory.low 它们允许您指示某些 cgroup 的内存应该受到更多保护,免受全局压力的影响,而其他 cgroup 的内存如果需要释放 RAM 则可以更灵活地使用。
文件 memory.pressure 它揭示了一些非常有用的指标:该 cgroup 中的任务因内存不足而被阻塞的时长,分别以 10 秒、60 秒和 300 秒为时间间隔。该变体 一些 它表明是否至少有一项任务被延误,以及 , 它反映了团队所有任务同时受到影响的时刻。
除了内核的 OOM killer 之外,还出现了用户空间解决方案,例如: Earlyoom, 诺汉 o systemd-oomdEarlyOOM 会监控 RAM 和交换空间,当它们低于某些阈值时,它会主动终止进程。 oom_score 提高温度,在机器死机前恢复可用性。
NoHang 更进一步:它支持更多选择标准,可以考虑内存压力,并且能够很好地与高级配置集成,尽管其开发过程并非一帆风顺。与此同时,systemd-oomd直接与 systemd 和 cgroup v2 集成,目前是许多发行版中用于更智能、更精细地管理低内存情况的首选方案。
现代交换机制:zram、zswap 和设备优先级
除了“经典”的磁盘交换之外,Linux 还提供了现代机制,通过结合RAM 压缩和选择性磁盘使用,大大提高了性能。
zram是一个内核模块,它会在 RAM 内部创建块设备,并将页面以压缩状态存储在这些块设备中。这些块设备通常用作超高速交换设备:压缩和解压缩会消耗一些 CPU 资源,但可以增加逻辑内存容量并大幅减少磁盘使用量。
在许多发行版中,只需安装即可。 zram-tools o zram生成器 并启用其服务。例如,在 Debian 系统中,您可以使用 sudo apt install zram-tools 并激活 zramswap 使用 systemd。在 AlmaLinux 中,使用 sudo dnf install zram-generator 及其相应的服务。
另一方面,zswap充当磁盘交换分区前的压缩缓存。它首先尝试将交换页存储在压缩 RAM 中;只有当此缓存已满或页面不再活动时,才会写入实际的交换区域。这可以减少磁盘 I/O 并延长 SSD 的使用寿命,但会占用一些 CPU 资源。
当组合使用多个交换设备(例如,zram 和磁盘文件)时,调整以下参数至关重要: 优先级。 同 swapon -p 或选项 pri= en /etc/fstab 您需要指定哪个设备优先使用。通常的做法是给 ZRAM 赋予高优先级(例如 100),给磁盘交换空间赋予低优先级(10),以便内核在访问磁盘之前充分利用 RAM 中压缩的交换空间。
服务器内存管理:交换、服务和安全性
在Web服务器(Apache、Nginx)、数据库(MySQL、MariaDB、MongoDB)或资源密集型应用程序中,内存是至关重要的资源。RAM和交换空间的配置直接决定了系统在开始出现瓶颈之前能够处理多少并发请求。
对于像 MongoDB 这样的数据库引擎来说,物理内存必须大于数据库的需求,这一点至关重要;否则,数据库将开始使用交换空间,由于内存访问和磁盘访问之间的显著差异,性能将急剧下降。MySQL/MariaDB 也存在同样的问题,像 MySQLTuner 这样的工具会根据可用内存推荐内存参数。
为避免浪费内存,建议停止未使用的服务,并清理不再需要的容器、镜像和 Docker 卷。在开发和测试环境中,很容易积累一些被遗忘的资源,这些资源会在无人察觉的情况下占用数 GB 的内存和磁盘空间。
安全因素也发挥了作用: 打开不必要的端口 它们会扩大攻击面。例如,成功入侵系统的恶意软件可以启动占用 CPU 和内存的挖矿进程,并在系统中调度任务。 crontab 并可能导致系统崩溃。检查传入和传出的端口、关闭所有非必要的进程以及清理可疑的定时任务都是基本的系统卫生措施,这些措施也有助于保护内存资源。
内存和文件系统:ext4、XFS、Btrfs 和日志记录
虽然这看似是一个独立的问题,但文件系统的选择及其配置也会影响内存行为和 I/O 负载。例如,Ext4 使用日志,根据负载情况,这可能会给磁盘带来额外的压力,从而影响缓存管理。
在对服务器性能要求较高的环境中,许多管理员会选择XFS甚至Btrfs。XFS通常在处理大型文件和高性能系统时表现出色。Btrfs 提供快照、透明压缩和子卷等高级功能,但代价是其复杂性较高,并且根据版本和发行版的不同,其在所有工作负载下的成熟度仍存在争议。
内核会根据文件系统的特性调整其缓存和写入策略,因此从 ext4 切换到 XFS 或 Btrfs 不仅会影响原始 I/O,还会影响 RAM 和页面缓存如何使用来缓冲读写操作。
管理员必备的图形工具和实用程序
虽然终端仍然是管理员的瑞士军刀,但也有一些工具可以大大简化内存和资源的管理。其中之一就是Glances,它是一款实时监控工具,可以在单个屏幕上显示 CPU、内存、磁盘、网络和进程,并提供可选的 Web 界面,方便用户通过浏览器监控多台服务器。
在 Debian 系统上快速安装,只需…… sudo apt install glances眼神交流与……非常相配 htop, vmstat y sar从而更直观地展现系统在负载下的运行情况。
在图形化服务器管理领域,Cockpit提供了一个用户友好的 Web 界面,用于监控内存、进程和服务。它允许您从单个控制台管理多台服务器,启动和停止 systemd 单元,监控交换空间和 zram 使用情况,以及在不离开浏览器的情况下查看日志。
在桌面系统中,许多发行版都集成了自己的资源监视器,但对于没有 GUI 的环境或需要轻量级工具的情况,将这些控制台工具与自定义脚本结合使用,可以让你随时清楚地了解内存的使用情况。
Linux 中正确的内存管理需要理解内核如何使用 RAM、交换空间、zram 和 zswap 的作用、cgroup v2 和各种 OOM 事件如何应对内存压力,以及有哪些工具可以用来监控和优化系统。当你把所有这些要素整合起来——从free、vmstat、PSS 和 memory.pressure 到 zram、swappiness 和 systemd-oomd——你就能摆脱“Linux 占用大量内存”的困扰,拥有一个经过精心调校、稳定可靠的系统,能够在任何角色(服务器、桌面或高负载环境)下最大限度地发挥硬件性能。