Linux 内存管理:Page Cache、Swap 与 OOM

举报
yd_214313748 发表于 2026/11/11 18:36:10 2026/11/11
【摘要】 Linux 内存管理:Page Cache、Swap 与 OOM 一、Linux 内存管理概述Linux 内存管理是操作系统内核的重要组成部分,负责物理内存分配、虚拟内存映射、页面缓存、内存回收以及内存不足时的资源管理。与一些操作系统不同,Linux 会尽可能利用空闲内存作为缓存,以减少磁盘 I/O,提高文件访问效率。因此,系统显示的内存使用量并不完全等于应用程序实际占用的内存。理解 Li...

Linux 内存管理:Page Cache、Swap 与 OOM

一、Linux 内存管理概述

Linux 内存管理是操作系统内核的重要组成部分,负责物理内存分配、虚拟内存映射、页面缓存、内存回收以及内存不足时的资源管理。

与一些操作系统不同,Linux 会尽可能利用空闲内存作为缓存,以减少磁盘 I/O,提高文件访问效率。因此,系统显示的内存使用量并不完全等于应用程序实际占用的内存。

理解 Linux 内存管理,需要重点掌握三个核心机制:

  • Page Cache(页缓存):利用物理内存缓存文件数据,减少磁盘访问。
  • Swap(交换空间):将部分匿名内存页面换出到磁盘,在内存压力较大时释放物理内存。
  • OOM(Out Of Memory):当内核无法满足内存分配需求时,通过回收资源或终止进程缓解内存不足。

这三个机制共同构成了 Linux 在内存利用率、I/O 性能和系统稳定性之间的平衡机制。

二、Linux 虚拟内存管理

2.1 什么是虚拟内存

Linux 使用虚拟内存机制,为每个进程提供独立的虚拟地址空间。

应用程序访问的地址通常是虚拟地址,而不是直接访问物理内存地址。CPU 通过 MMU(Memory Management Unit,内存管理单元)将虚拟地址转换为物理地址。

虚拟内存主要带来以下优势:

  1. 进程隔离:不同进程拥有独立的虚拟地址空间。
  2. 内存保护:通过页表权限控制读、写和执行操作。
  3. 内存共享:多个进程可以映射同一物理内存区域。
  4. 按需分配:虚拟地址空间可以先建立映射,在实际访问时再分配物理页面。
  5. 内存扩展:结合 Swap,可以在一定程度上突破物理内存容量限制。

2.2 虚拟地址空间布局

Linux 进程的虚拟地址空间通常包含以下区域:

内存区域 作用
Text Segment 存放程序机器指令,通常具有只读和可执行权限
Data Segment 存放已初始化的全局变量和静态变量
BSS Segment 存放未初始化或初始化为零的全局变量和静态变量
Heap 动态内存分配区域
Memory Mapping 映射共享库、文件和匿名内存
Stack 存放函数调用栈、局部变量等

可以通过以下命令查看进程的内存映射:

cat /proc/<PID>/maps

例如:

cat /proc/1234/maps

也可以使用:

pmap -x 1234

查看进程各内存映射区域的大小和使用情况。

2.3 内存页与页表

Linux 以页(Page)作为内存管理的基本单位。

在常见的 x86-64 系统中,基础页大小通常为 4 KiB。

查看系统页大小:

getconf PAGE_SIZE

输出:

4096

虚拟内存管理过程中,内核通过页表记录虚拟页面与物理页面之间的映射关系。

当进程访问尚未建立有效物理映射的页面时,CPU 会触发 Page Fault(缺页异常),由内核判断如何处理。

缺页异常并不一定意味着程序发生错误,常见情况包括:

  • 首次访问尚未分配物理页面的匿名内存。
  • 访问尚未加载到内存的文件页面。
  • 触发 Copy-on-Write(写时复制)。
  • 访问已经被换出到 Swap 的页面。

只有当访问行为违反内存映射权限或访问非法地址时,才可能产生无法恢复的缺页异常,最终导致进程收到 SIGSEGV 等信号。

三、Page Cache:Linux 页缓存机制

3.1 什么是 Page Cache

Page Cache 是 Linux 内核用于缓存文件数据的主要机制。

当应用程序读取文件时,内核通常会先检查文件对应的数据是否已经存在于 Page Cache 中。

如果缓存命中,内核可以直接从内存提供数据,避免磁盘 I/O。

如果缓存未命中,内核需要从存储设备读取数据,并将其缓存到内存中。

其基本流程如下:

应用程序读取文件
        |
        v
     系统调用
        |
        v
   检查 Page Cache
        |
   +----+----+
   |         |
 缓存命中   缓存未命中
   |         |
   v         v
读取内存   读取磁盘
   |         |
   |         v
   |      写入缓存
   |         |
   +----+----+
        |
        v
   返回应用程序

Page Cache 的主要作用:

  • 减少磁盘读取次数。
  • 提高文件读取速度。
  • 减少存储设备随机 I/O。
  • 缓存文件写入数据。
  • 提高系统整体 I/O 吞吐量。

3.2 Page Cache 的工作原理

Linux 通过文件页缓存机制管理文件数据。

当应用程序执行:

read(fd, buffer, size);

内核会根据文件偏移量查找对应的缓存页面。

如果数据已经存在于 Page Cache 中,可以直接从缓存读取。

如果不存在,则需要从底层文件系统和存储设备读取数据。

例如:

cat largefile.bin > /dev/null

第一次读取文件时,可能需要从磁盘加载数据。

再次读取时,如果缓存仍然保留在内存中,就可能直接从 Page Cache 获取数据。

可以通过以下方式观察缓存变化:

free -h

重点关注:

              total        used        free      shared  buff/cache   available
Mem:           31Gi        8Gi         2Gi        300Mi       21Gi        22Gi
Swap:          8Gi         0B          8Gi

其中:

  • free:完全未使用的物理内存。
  • buff/cache:用于缓冲区和缓存的内存。
  • available:内核估算的可供新应用程序使用的内存。

不能简单地将 free 较低判断为内存不足。Linux 会主动利用空闲内存缓存文件数据,在应用程序需要内存时,可以回收其中一部分缓存。

3.3 Clean Page 与 Dirty Page

Page Cache 中的页面可以分为干净页和脏页。

Clean Page(干净页)

缓存数据与磁盘中的文件内容一致。

如果系统内存不足,干净页通常可以直接回收。后续再次访问时,内核可以重新从磁盘读取。

Dirty Page(脏页)

缓存数据已经被修改,但尚未写回磁盘。

例如:

echo "Hello Linux" > test.txt

文件写入操作可能先修改内存中的缓存页面,并将其标记为脏页,之后再由内核异步写回存储设备。

脏页的写回过程:

应用程序写入文件
        |
        v
   修改 Page Cache
        |
        v
     标记 Dirty
        |
        v
   后台写回机制
        |
        v
     磁盘存储
        |
        v
   标记为 Clean

可以通过以下命令查看脏页统计:

grep -E 'Dirty|Writeback' /proc/meminfo

常见字段:

字段 说明
Dirty 尚未写回的脏页内存
Writeback 正在写回磁盘的内存

3.4 Page Cache 与内存回收

当系统出现内存压力时,内核会尝试回收不再需要的内存。

对于 Page Cache:

  • 干净页通常可以直接丢弃。
  • 脏页通常需要先写回磁盘。
  • 正在使用或被锁定的页面可能无法立即回收。

因此,Page Cache 并不是永久占用内存的区域,而是可以根据系统负载动态调整的缓存。

查看内存详细信息:

cat /proc/meminfo

重点关注:

MemTotal
MemFree
MemAvailable
Buffers
Cached
Dirty
Writeback
Active
Inactive

3.5 如何清理 Page Cache

Linux 提供了 drop_caches 接口,可以主动释放部分缓存。

执行前建议先同步脏页:

sync

释放 Page Cache:

echo 1 > /proc/sys/vm/drop_caches

释放 dentry 和 inode 缓存:

echo 2 > /proc/sys/vm/drop_caches

同时释放:

echo 3 > /proc/sys/vm/drop_caches

对应关系:

值 操作
1 释放干净的 Page Cache
2 释放可回收的 dentry 和 inode
3 同时释放上述两类缓存

需要注意:

  • drop_caches 不会释放正在使用的内存。
  • 不会主动清理脏页。
  • 不会释放应用程序正在使用的匿名内存。
  • 清理缓存后,后续文件访问可能重新产生磁盘 I/O。

因此,生产环境不建议定期执行 drop_caches 作为常规内存优化手段。

四、Swap:Linux 交换空间机制

4.1 什么是 Swap

Swap 是 Linux 提供的交换空间机制,用于在物理内存压力较大时,将部分内存页面换出到磁盘。

Swap 可以使用独立分区,也可以使用普通文件。

当物理内存不足时,内核可以将暂时不活跃的匿名内存页面写入 Swap,从而释放物理内存供其他进程使用。

需要明确:

Swap 不是物理内存的等价替代品。

磁盘存储的访问延迟通常远高于 RAM。频繁发生 Swap 换入和换出,会显著影响系统性能。

4.2 Swap 的工作原理

Linux 内存管理主要涉及两类页面:

  • 文件支持页面(File-backed Pages):例如文件映射和 Page Cache。
  • 匿名页面(Anonymous Pages):例如进程堆、栈以及匿名内存映射。

干净的文件支持页面通常可以直接丢弃,后续从文件重新读取。

匿名页面没有可直接重新读取的文件作为数据来源,因此在需要回收时,可能需要先写入 Swap。

Swap 的基本工作流程:

系统物理内存压力增加
        |
        v
   内核启动内存回收
        |
        v
  选择可回收的内存页面
        |
   +----+----+
   |         |
 文件页面   匿名页面
   |         |
   v         v
干净页丢弃  写入 Swap
   |         |
   +----+----+
        |
        v
   释放物理内存
        |
        v
   满足新的内存分配

当进程再次访问已经换出的匿名页面时,会触发缺页异常,内核再从 Swap 中读取数据并恢复到物理内存。

这一过程称为 Swap In。

将内存页面写入 Swap 称为 Swap Out。

4.3 Swap 分区与 Swap 文件

Linux 支持两种常见 Swap 形式。

Swap 分区

使用独立磁盘分区作为交换空间。

查看磁盘分区:

lsblk

创建 Swap 分区后,可以使用:

mkswap /dev/sdXn
swapon /dev/sdXn

Swap 文件

使用普通文件作为交换空间。

例如创建 4 GiB Swap 文件:

fallocate -l 4G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile

检查:

swapon --show
free -h

需要注意,部分文件系统对 Swap 文件有额外要求,例如 Btrfs 通常需要按照其 Swap 文件规范创建文件,不能直接套用普通文件系统的创建方式。

4.4 Swap 持久化配置

如果希望系统重启后自动启用 Swap,可以修改 /etc/fstab。

例如:

vim /etc/fstab

添加:

/swapfile none swap sw 0 0

执行:

swapon -a

检查:

swapon --show

4.5 vm.swappiness

vm.swappiness 用于控制内核在内存回收过程中使用 Swap 的倾向。

查看:

sysctl vm.swappiness

修改:

sysctl -w vm.swappiness=10

持久化:

vm.swappiness = 10

常见理解:

设置趋势 行为倾向
较低 降低主动使用 Swap 的倾向
较高 更积极地考虑将匿名页面换出
0 显著降低 Swap 使用倾向,但不等于绝对禁用

需要注意,现代 Linux 内核的内存回收机制比简单的“内存用完才使用 Swap”复杂得多。内核会根据页面活跃程度、回收成本和内存压力综合判断。

因此,不能简单认为 swappiness=1 一定比 swappiness=60 更适合所有服务器。

4.6 Swap 使用情况监控

查看 Swap 总体使用量:

free -h

查看 Swap 设备:

swapon --show

查看内存交换活动:

vmstat 1

重点关注:

字段 含义
si 每秒从 Swap 换入的内存量
so 每秒向 Swap 换出的内存量

例如:

procs -----------memory---------- ---swap-- -----io----
 r  b   swpd   free   buff  cache   si   so    bi    bo
 1  0      0  204800  1024  409600    0    0     2     5
 2  1 1048576  102400 1024  204800  512  1024   10   100

如果 si 和 so 长时间持续较高,通常说明系统存在明显的内存交换活动。

但 Swap 已使用量较高并不一定代表当前存在内存压力。某些页面可能在较早之前被换出,之后一直没有再次访问。

判断是否存在 Swap 瓶颈,应结合换入换出速率、内存压力、I/O 延迟和应用响应时间。

五、OOM:Linux 内存不足处理机制

5.1 什么是 OOM

OOM(Out Of Memory)指系统无法满足内存分配需求的状态。

当内核尝试通过内存回收、页面换出等方式释放内存,但仍然无法满足关键内存分配请求时,可能触发 OOM Killer。

OOM Killer 是 Linux 内核中的内存不足处理机制,用于选择并终止部分进程,释放其占用的内存资源。

其主要目标是:

  • 避免系统因内存耗尽而完全失去响应。
  • 释放足够的内存以恢复系统运行。
  • 尽可能选择对系统整体影响较小的进程。

需要注意,OOM 不一定意味着物理内存和 Swap 都完全耗尽。内存分配限制、内存碎片以及特定内存分配条件,也可能导致分配失败。

5.2 OOM Killer 工作流程

当内核遇到无法满足的内存分配请求时,会尝试进行内存回收。

如果回收无法解决问题,内核可能进入 OOM 处理流程:

进程申请内存
      |
      v
  检查内存资源
      |
      v
  尝试内存回收
      |
      v
  是否满足分配?
      |
  +---+---+
  |       |
 是       否
  |       |
  v       v
分配内存  进入 OOM 处理
          |
          v
      计算进程评分
          |
          v
      选择受害进程
          |
          v
       终止进程
          |
          v
       释放内存

OOM Killer 并不是简单地终止内存占用最大的进程,而是根据多个因素计算进程的 OOM 评分。

5.3 OOM Score 与 OOM Score Adj

Linux 为每个进程提供 OOM 评分机制。

查看进程 OOM 评分:

cat /proc/<PID>/oom_score

查看评分调整值:

cat /proc/<PID>/oom_score_adj

oom_score 表示内核计算出的 OOM 选择评分,通常分值越高,被选中的可能性越大。

oom_score_adj 用于调整进程在 OOM 选择中的优先级。

其取值范围:

-1000 ~ 1000

含义:

值 作用
-1000 完全禁止该进程被常规 OOM Killer 选中
0 默认调整值
1000 最大程度提高被选中的倾向

例如:

降低某个进程被 OOM Killer 选中的倾向:

echo -500 > /proc/<PID>/oom_score_adj

提高某个进程被选中的倾向:

echo 500 > /proc/<PID>/oom_score_adj

需要注意:

  • 修改其他用户进程的该参数通常需要足够权限。
  • oom_score_adj=-1000 不应随意用于普通业务进程。
  • 保护过多关键进程可能导致 OOM 时缺少可终止对象,使系统更难恢复。
  • 该机制不能代替服务资源限制和内存监控。

5.4 查看 OOM 日志

OOM 事件通常会记录在内核日志中。

查看:

dmesg -T | grep -i -E 'oom|killed process|out of memory'

使用 journalctl:

journalctl -k | grep -i -E 'oom|killed process|out of memory'

典型日志:

Out of memory: Killed process 1234 (java) total-vm:8192000kB, anon-rss:2048000kB

常见字段:

字段 含义
Killed process 被终止的进程及 PID
total-vm 进程虚拟内存总量
anon-rss 进程驻留在物理内存中的匿名页面大小
file-rss 进程驻留在物理内存中的文件映射页面大小

排查 OOM 时,应重点关注进程的实际 RSS、内存增长趋势以及是否存在内存泄漏,而不是只看虚拟内存大小。

5.5 OOM 与内存泄漏

OOM 的常见原因包括:

  1. 应用程序存在内存泄漏。
  2. 并发请求过多,导致瞬时内存需求过高。
  3. 数据库缓存或应用缓存设置不合理。
  4. 容器内存限制过低。
  5. 系统物理内存不足。
  6. 内核内存或其他受限内存资源耗尽。

对于长期运行的服务,可以通过监控 RSS 变化判断是否存在持续内存增长。

例如:

ps -eo pid,comm,rss,%mem --sort=-rss | head -20

其中 RSS 表示进程当前驻留在物理内存中的页面大小,单位通常为 KiB。

如果某个进程 RSS 长期持续增长,且业务负载没有相应变化,就需要进一步检查应用程序的内存分配和释放逻辑。

六、Linux 内存回收机制

6.1 什么是内存回收

当系统内存不足时,Linux 内核会尝试回收可用页面,以满足新的内存分配请求。

内存回收主要包括:

  • 回收干净的文件缓存页面。
  • 将脏页写回存储设备。
  • 将部分匿名页面换出到 Swap。
  • 回收可释放的内核缓存和其他内存对象。

Linux 内存回收主要分为两种模式。

直接回收(Direct Reclaim)

当进程申请内存但系统可用内存不足时,内核可能要求当前进程参与内存回收。

这种情况下,内存分配请求可能需要等待回收完成,从而增加应用程序延迟。

后台回收(Background Reclaim)

内核通过 kswapd 后台线程进行内存回收。

当空闲内存低于一定水位时,kswapd 会尝试回收页面,使系统维持足够的可用内存。

6.2 kswapd 线程

kswapd 是 Linux 内核中的后台内存回收线程。

查看:

ps -ef | grep kswapd

它主要负责:

  • 扫描内存页面。
  • 回收可回收的文件缓存。
  • 在必要时将匿名页面换出。
  • 维持内存水位。

如果系统持续处于内存压力状态,kswapd 可能频繁运行,造成 CPU 和存储 I/O 开销。

6.3 内存水位机制

Linux 使用内存水位机制控制后台回收和内存分配。

常见水位包括:

水位 作用
min 最低内存水位,表示系统需要高度重视内存压力
low 低水位,通常会触发后台回收
high 高水位,后台回收通常会持续到目标水位附近

查看相关信息:

cat /proc/zoneinfo

也可以查看:

cat /proc/buddyinfo

这些信息主要用于分析内核内存区域、水位和物理内存分配情况。

6.4 内存碎片与连续内存分配

物理内存虽然可能存在大量空闲页面,但这些页面不一定连续。

当内核需要分配较大的连续物理内存区域时,可能因为内存碎片而无法满足请求。

Linux 使用伙伴系统(Buddy System)管理物理页面分配。

查看:

cat /proc/buddyinfo

该文件展示不同内存区域中各阶空闲页面的数量。

例如:

Node 0, zone Normal  120  60  30  15  8  4  2  1

每一列代表不同阶数的空闲块数量。阶数越高,对应的连续物理页面数量越多。

对于需要大块连续物理内存的内核分配请求,内存碎片可能成为分配失败的原因。

七、Linux 内存监控与分析

7.1 使用 free 查看内存

free -h

示例:

               total        used        free      shared  buff/cache   available
Mem:             32Gi        12Gi        2Gi        500Mi       18Gi        19Gi
Swap:             8Gi         1Gi        7Gi

重点字段:

字段 说明
total 系统总内存
used 已使用内存,具体统计口径受版本和实现影响
free 完全空闲内存
shared 主要表示 tmpfs 等共享内存使用量
buff/cache 缓冲区与缓存
available 内核估算的可供新应用使用的内存

其中 available 比 free 更适合判断系统是否还有足够的可用内存。

7.2 使用 /proc/meminfo

cat /proc/meminfo

常见字段:

字段 说明
MemTotal 可用物理内存总量
MemFree 完全空闲内存
MemAvailable 估算可用内存
Buffers 块设备相关缓冲区
Cached 文件缓存相关内存
Active 最近活跃的内存页面
Inactive 相对不活跃的内存页面
SwapTotal Swap 总容量
SwapFree 剩余 Swap 容量
Slab 内核 Slab 分配器使用的内存
SReclaimable 可回收的 Slab 内存
SUnreclaim 不可回收的 Slab 内存
Dirty 脏页内存
Writeback 正在写回的内存

7.3 使用 vmstat 监控内存

vmstat 1

常见字段:

字段 说明
r 等待运行的进程数
b 不可中断睡眠的进程数
swpd 已使用 Swap 容量
free 空闲内存
buff 缓冲区内存
cache 缓存内存
si Swap 换入速率
so Swap 换出速率
bi 块设备读取速率
bo 块设备写入速率

如果 si 和 so 持续较高,同时系统响应时间明显增加,可能存在严重内存压力。

7.4 使用 sar 监控内存

安装 sysstat:

# Debian / Ubuntu
apt install sysstat

# RHEL / CentOS
dnf install sysstat

查看内存统计:

sar -r 1

查看 Swap 活动:

sar -W 1

通过持续采集历史数据,可以分析内存使用趋势,而不是只依赖某一时刻的内存快照。

7.5 使用 smem 分析进程内存

普通 ps 命令显示的 RSS 可能重复计算多个进程共享的物理页面。

smem 可以通过 PSS(Proportional Set Size)等指标,更合理地分摊共享内存。

安装:

apt install smem

查看进程内存:

smem -tk

常见指标:

指标 含义
USS 进程独占的物理内存
PSS 独占内存加上按比例分摊的共享内存
RSS 进程驻留的物理内存总量

对于多个进程共享大量动态库或共享内存的场景,PSS 通常比简单累加 RSS 更适合分析整体内存占用。

八、容器环境中的内存管理

容器并不拥有独立的物理内存,而是通过 Linux cgroup 对进程使用的资源进行限制。

Docker、Kubernetes 等容器平台都依赖这一机制管理容器内存。

8.1 Docker 内存限制

例如:

docker run -d \
  --name memory-test \
  --memory=1g \
  --memory-swap=2g \
  nginx

其中:

  • --memory=1g:限制容器内存使用上限为 1 GiB。
  • --memory-swap=2g:限制容器内存与 Swap 总量为 2 GiB。

在该配置下,容器理论上最多可以使用约 1 GiB 的 Swap。

需要注意,Docker 的 --memory-swap 表示内存与 Swap 的总限制,而不是单独的 Swap 容量。实际行为还受到宿主机 Swap 配置、Docker 版本和 cgroup 实现影响。

8.2 cgroup v2 内存指标

在使用 cgroup v2 的系统中,容器内存控制通常通过以下文件实现:

/sys/fs/cgroup/<容器对应路径>/

常见文件:

文件 作用
memory.current 当前内存使用量
memory.max 内存使用上限
memory.high 内存高水位控制
memory.swap.current 当前 Swap 使用量
memory.swap.max Swap 使用上限
memory.stat 内存分类统计
memory.events 内存压力和限制事件统计

查看:

cat /sys/fs/cgroup/memory.current
cat /sys/fs/cgroup/memory.max
cat /sys/fs/cgroup/memory.stat
cat /sys/fs/cgroup/memory.events

其中 memory.events 可以用于观察容器是否触发内存限制。

8.3 容器 OOM 与宿主机 OOM

容器环境中需要区分两种情况:

容器级 OOM

容器超过自身 cgroup 内存限制时,内核可能触发该 cgroup 范围内的 OOM 处理。

宿主机级 OOM

宿主机整体内存不足时,可能触发全局 OOM Killer,影响宿主机上的多个进程和容器。

查看 Docker 容器状态:

docker inspect <容器名称> \
  --format '{{.State.OOMKilled}}'

查看容器内存使用:

docker stats

如果容器频繁出现 OOM,应结合 memory.events、容器日志、应用程序 RSS 和宿主机内存情况判断原因。

九、内存管理常见问题

9.1 Linux 内存占用很高,但应用程序并没有使用那么多内存

这通常是 Page Cache 导致的。

Linux 会利用空闲内存缓存文件数据,因此 free 显示的空闲内存可能较少。

判断系统内存是否紧张,应重点关注:

free -h

以及:

grep -E 'MemAvailable|Cached|Dirty|SwapFree' /proc/meminfo

如果 MemAvailable 仍然充足,通常不需要主动清理缓存。

9.2 为什么关闭 Swap 后系统反而更容易 OOM?

关闭 Swap 后,系统失去了将部分匿名内存页面换出的能力。

当物理内存压力较大时,内核只能依赖其他可回收页面和内存回收机制。

如果匿名内存占用很高,可能更早触发 OOM。

Swap 并不能解决内存不足的根本问题,但在部分场景中可以为系统提供一定的缓冲空间。

9.3 Swap 已经使用很多,为什么系统仍然有大量可用内存?

Swap 中的页面可能是在此前内存压力较大时换出的。

即使后来系统释放了大量物理内存,这些页面也不一定会立即换回。

因此:

  • Swap 使用量高不代表当前一定存在内存压力。
  • Swap 使用量低也不代表系统一定没有内存压力。
  • 应重点关注 si、so 是否持续增长,以及应用程序响应时间。

9.4 OOM 为什么会杀死内存占用最大的进程?

OOM Killer 会综合考虑进程内存占用、OOM 调整值以及其他因素。

它并不是简单地选择 RSS 最大的进程。

此外,容器级 OOM 和全局 OOM 的选择范围也可能不同。

9.5 如何判断系统是否正在发生内存抖动?

内存抖动通常表现为:

  • Swap 持续换入和换出。
  • 磁盘 I/O 明显增加。
  • CPU 时间大量消耗在内存回收。
  • 应用程序响应延迟增加。
  • 系统吞吐量下降。

可以结合以下命令分析:

vmstat 1
sar -W 1
free -h

如果系统持续发生大量 Swap In / Swap Out,且伴随明显的性能下降,应考虑减少应用程序内存占用、调整并发规模或增加物理内存。

十、Linux 内存调优实践

内存调优不应该以追求较低的内存使用率为目标,而应关注系统是否能够在合理的资源消耗下保持稳定运行。

10.1 监控优先

建议建立以下监控指标:

  • MemAvailable。
  • Page Cache 和 Dirty。
  • Swap 使用量及换入换出速率。
  • 进程 RSS、PSS。
  • 内存回收活动。
  • OOM 事件数量。
  • 容器内存限制触发情况。

10.2 合理配置 Swap

是否启用 Swap,需要结合系统用途判断。

场景 建议
普通服务器 可以保留适量 Swap,作为内存压力缓冲
数据库服务器 根据数据库内存管理策略和延迟要求决定
桌面系统 保留 Swap 通常有助于应对内存压力
容器宿主机 结合容器资源限制和运行时策略配置
高性能计算 根据任务延迟和内存需求评估是否使用

10.3 避免盲目清理缓存

Page Cache 能够提高文件访问效率。

频繁清理缓存会导致后续文件访问重新产生磁盘 I/O,反而降低性能。

除非是在进行特定的性能测试或故障排查,否则不建议将 drop_caches 纳入日常运维任务。

10.4 合理设置容器内存限制

容器内存限制应根据实际业务负载设置。

限制过低可能导致容器频繁 OOM,限制过高则可能使单个容器占用过多宿主机资源。

建议结合业务峰值、内存增长趋势和安全余量进行配置。

10.5 定位内存泄漏

对于长期运行的服务,应关注进程内存是否持续增长。

可以使用:

ps -eo pid,comm,rss,%mem --sort=-rss | head -20

持续观察进程 RSS。

如果发现内存持续增长,可以进一步使用应用程序自身的内存分析工具、堆分析工具或性能分析器定位问题。

十一、总结

Linux 内存管理并不是简单地将数据装入物理内存,而是通过虚拟内存、Page Cache、Swap、内存回收和 OOM 等机制协调系统资源。

三项核心机制的关系可以概括为:

机制 核心作用 主要目标
Page Cache 缓存文件数据 提高文件 I/O 性能
Swap 将部分匿名页面换出到磁盘 缓解物理内存压力
OOM Killer 终止部分进程释放内存 避免系统因内存耗尽而无法继续运行

在 Linux 运维和性能分析中,需要建立以下认识:

  1. 内存使用率高不一定代表内存不足,Page Cache 是正常的内存利用方式。
  2. Swap 是内存管理机制的一部分,不应简单视为异常。
  3. OOM 不一定意味着物理内存和 Swap 已经全部耗尽。
  4. 内存回收可能影响应用程序延迟,需要关注直接回收和后台回收。
  5. 容器内存限制依赖 cgroup,必须区分容器级 OOM 和宿主机级 OOM。
  6. 内存调优应以监控数据和实际负载为依据,而不是盲目修改内核参数。

理解这些机制,有助于定位 Linux 服务器内存占用异常、Swap 活动过高、应用程序内存泄漏以及 OOM 等常见问题。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。