Linux 内存控制参数汇总
sysctl 控制参数
下表列出一些常见的 Linux (Kernel 5.3)内存相关的调节参数,具体参数根据内核版本可能有所不同,其使用场景和含义需要查看对应内核版本的相关文档
Option | Default Value | Description | Examples |
---|---|---|---|
vm.dirty_background_bytes /proc/sys/vm/dirty_background_bytes |
0 bytes | 0 表示使用 vm.dirty_background_ratio 来决定将内存脏页(Memroy Dirty Pages)写回磁盘的阈值而不是使用 vm.dirty_background_bytes - 设置为相对较高的值,会使内存中的数据延迟写入磁盘,产生较小的 IOPS,但是可能会导致数据不一致或丢失 - 设置为相对较低的值,会使内存数据及时写入磁盘,导致 IOPS 较高,数据丢失或不一致的风险较低 |
|
vm.dirty_background_ratio /proc/sys/vm/dirty_background_ratio |
10 | 默认当内存脏页数据达到内存大小的 10% 时,在后台触发 per-bdi writeback (Linux 早期(Linux 内核 3.0 之前)由 pdflush 负责处理脏页(dirty pages)写回磁盘的机制)将脏页数据写回磁盘。回写(Write-Back)操作由统一的内核线程 kworker 或 flush-<设备名> 处理 |
|
vm.dirty_bytes /proc/sys/vm/dirty_bytes |
0 bytes | 定义强制写回的脏页阈值(以字节为单位)。 | |
vm.dirty_ratio /proc/sys/vm/dirty_ratio |
20 | 定义强制写回的脏页阈值(以总内存的百分比表示)。 | |
vm.dirty_writeback_centisecs /proc/sys/vm/dirty_writeback_centisecs |
500 | 定义写回线程的执行间隔(以百分之一秒为单位)。 | |
vm.dirty_expire_centisecs /proc/sys/vm/dirty_expire_centisecs |
3000 | 定义脏页的最大“年龄”(超过这个时间的脏页会被优先写回)。 如需手动执行写回操作,可以使用命令 sync |
|
vm.min_free_kbytes /proc/sys/vm/min_free_kbytes |
通常为 min_free_kbytes = sqrt(总内存 * 16) |
控制系统保留的最小空闲内存量(以 KB 为单位),确保系统在内存压力下仍有足够的内存用于关键操作,如处理中断、内核操作等。 如果设置过小 - 系统可能在内存紧张时无法及时回收内存,导致性能下降。 - 网络流量或 I/O 密集型任务可能因内存分配失败而中断。 - 可能增加系统触发 OOM(Out-Of-Memory)的风险。 如果设置过大 : - 系统可用内存减少,因为更多内存被预留。 - 可能导致用户空间任务频繁触发内存回收,降低整体性能。 |
|
vm.watermark_scale_factor /proc/sys/vm/watermark_scale_factor |
10 | 内核的内存水位标记( watermarks )机制 |
|
vm.watermark_boost_factor /proc/sys/vm/watermark_boost_factor |
15000 | 在内存压力下临时提升水位,保证一定的空闲内存。 | |
vm.percpu_pagelist_high_fraction /proc/sys/vm/percpu_pagelist_high_fraction |
0 | vm.percpu_pagelist_high_fraction | |
vm.overcommit_memory /proc/sys/vm/overcommit_memory vm.overcommit_ratio vm.overcommit_kbytes |
Linux 内存 Overcommit 机制详解 | ||
vm.swappiness /proc/sys/vm/swappiness |
60 | 控制 内核在内存不足前主动使用 Swap 的程度,取值范围:0 - 100 。- 0 :尽可能 **不使用 Swap** ,只有在内存耗尽时才使用(适合数据库、低延迟应用)。<br/>- 100` : 尽可能 频繁使用 Swap(适合桌面系统) 。 |
|
vm.vfs_cache_pressure |
100 | vm.vfs_cache_pressure |
|
vm.admin_reserve_kbytes /proc/sys/vm/admin_reserve_kbytes |
3% Free Pages | 为系统管理员保留一定量的内存,以防止在内存紧张时关键的管理任务(如登录、执行命令等)无法正常运行。这部分内存不会被普通用户进程占用,即使在系统内存紧张时也会保留。 | |
memory_failure_early_kill /proc/sys/vm/memory_failure_early_kill |
0 | 用于控制在发生内存故障时,系统是否立即将有问题的内存页标记为不可用,并杀死访问该内存的进程。 - 默认值是 0 ,表示不立即杀死进程。 - 启用后(值为 1) 当检测到内存错误时,系统会尽早杀死访问该内存的进程,以避免更多的系统崩溃或错误发生。 |
|
memory_failure_recovery /proc/sys/vm/memory_failure_recovery |
1 | 当检测到内存故障时,系统可以尝试 恢复错误的内存页 。 - 默认值是 1 ,表示启用内存恢复机制。 - 禁用后(值为 0) : 系统不尝试恢复内存错误,可能会更直接地采取 杀死进程 或 标记内存为不可用 的操作。 |
|
/proc/sys/vm/drop_caches |
默认值始终为 0 |
允许管理员手动清理 Linux 内存缓存,包括: - Page Cache(页面缓存) : 主要用于加速文件读取。- Dentry Cache(目录项缓存) : 记录文件路径信息,加快目录访问。- Inode Cache(索引节点缓存) : 记录文件元数据,如大小、权限等。drop_caches 不会影响进程已使用的内存,只是释放 内核缓存 。 适用于 测试、性能调优、观察内存使用情况 ,但不建议频繁使用。 可选值包括: - 1 : 清理 Page Cache ,释放文件数据缓存- 2 : 清理 Dentry 和 Inode Cache ,释放目录路径和文件元数据缓存- 3 : 清理 Page Cache 、 Dentry 和 Inode Cache (全部) |
建议同步数据到磁盘(sync )后清理,防止数据丢失 |
/proc/sys/vm/compact_memory |
默认值始终为 0 |
compact_memory |
vm.watermark_scale_factor
vm.watermark_scale_factor
(/proc/sys/vm/watermark_scale_factor
)是 Linux 内核中的一个虚拟内存管理参数,它影响内核的内存水位标记( watermarks
)机制。内存水位标记用于决定何时触发内存回收(如回收页缓存或启动交换操作)。通过调整该参数,可以控制内核在内存压力下的行为和回收策略。
Linux 内核为每个内存区域(zone
)定义了三个水位标记:
min(最低水位) :
当可用内存低于
min
时,内核强制触发回收机制,尽一切可能释放内存。low(低水位) :
内核尝试开始回收内存,但允许正常分配。
high(高水位) :
可用内存高于 high 时,内核不会主动回收内存。
这些水位标记在 /proc/zoneinfo
中可以查看:
cat /proc/zoneinfo | grep -E "Node|min|low|high" |
vm.watermark_scale_factor
是一个百分比值(默认值为 10,表示 10%
),用于调整内存水位的敏感度。具体来说:
它决定了内存水位的范围(
high
和low
之间的差距)。值越大,水位范围越大,内核对内存压力的响应越迟钝。
值越小,水位范围越小,内核对内存压力的响应越敏感。
内存水位的计算方式如下:
high = min_free_kbytes + (总内存 * watermark_scale_factor / 10000) |
增大 watermark_scale_factor
:
- 内存水位范围变大,内核对内存压力的响应变慢。
- 适用于内存充足且希望减少内存回收频率的场景。
- 过高值 可能导致系统在内存压力下响应过慢,增加 OOM(Out of Memory)风险。
减小 watermark_scale_factor
:
内存水位范围变小,内核对内存压力的响应变快。
适用于内存紧张且需要快速回收内存的场景。
过低值 可能导致内核频繁回收内存,增加系统开销。
vm.percpu_pagelist_high_fraction
从 Linux 5.16 及以后,vm.percpu_pagelist_fraction
已被移除,取而代之的是 vm.percpu_pagelist_high_fraction
,并且 PCP(Per-CPU Page List)大小的计算方式发生了变化。
什么是 PCP(Per-CPU Page List)?
Linux 内核的物理页框管理(Buddy System)采用 PCP(Per-CPU Page List,每 CPU 页列表) 机制,为每个 CPU 维护一个 独立的 页缓存,以减少多个 CPU 争夺全局锁,提高内存分配效率。
PCP 的作用 :
- 通过为每个 CPU 保留一定数量的空闲页,减少内存分配时对全局锁争用,加快小规模页分配,从而提高多核系统上的内存分配性能。
- 提高缓存命中率,避免频繁访问 Buddy System。每个 CPU 都有自己的空闲页列表,减少了多个 CPU 同时访问全局空闲列表时的锁争用。
PCP 主要参数 :
low
: 低水位,低于此值时,系统会回收页。high
: 高水位,达到此值时,释放多余页给 Buddy System。
vm.percpu_pagelist_high_fraction
控制 Per-CPU Page List(每 CPU 页列表)的上限(high limit) ,限制 PCP 过大导致的内存浪费。
Linux 内存 Overcommit 机制详解
在 Linux 内核中,Overcommit 机制决定了系统如何管理 虚拟内存(Virtual Memory) 申请,特别是当进程申请的内存超过物理 RAM + Swap 时的处理策略。
Linux 内核的 Overcommit 机制允许系统分配比实际物理内存更多的虚拟内存。这种机制基于以下假设:
并非所有分配的内存都会被实际使用。
应用程序可能会申请大量内存,但实际使用的只是其中一部分。
相关参数:
vm.overcommit_memory
—— 控制 Overcommit 策略(是否允许超额分配)。vm.overcommit_ratio
—— 影响可分配内存的计算。vm.overcommit_kbytes
—— 手动设置可 Overcommit 的最大内存(部分新内核支持)。
vm.overcommit_memory 是一个整数值,用于控制内核的内存分配策略。它有以下三种模式:
0(默认值) : Heuristic Overcommit(启发式 Overcommit)。
内核会根据当前系统的内存使用情况,使用启发式算法(基于历史数据)来决定是否允许内存分配。
允许进程请求比实际 RAM 多的内存
如果系统空闲内存较少,可能会拒绝内存分配请求。
这是最常用的模式,适用于大多数场景 。
1 : Always Overcommit(总是允许 Overcommit)。
内核总是允许内存分配请求,无论当前内存使用情况如何。程可以分配 任意大小 的虚拟内存,哪怕物理 RAM 和 Swap 不够。
这种模式下,系统可能会分配比实际物理内存更多的虚拟内存。
适用于内存密集型应用,但存在 OOM(Out-Of-Memory)风险。
2 : Strict Overcommit(禁止 Overcommit)。
内核会严格限制内存分配,确保分配的内存不超过
overcommit_ratio
或overcommit_kbytes
设置的限制。进程申请超出 CommitLimit 直接 失败(返回 ENOMEM) 。
这种模式下,系统不会分配超过物理内存和交换空间总和的内存。
适用于对内存使用要求严格的场景。
当 vm.overcommit_memory = 2
时,vm.overcommit_ratio
决定 CommitLimit (可分配的最大虚拟内存) 。overcommit_ratio
是一个百分比值,用于在 overcommit_memory=2
模式下限制内存分配。它定义了系统可以分配的内存总量与物理内存的比例。 默认值 :通常为 50
(即 50%
)。
允许分配的内存总量 = 物理内存 × (overcommit_ratio / 100) + 交换空间 |
例如,如果物理内存为 16GB,overcommit_ratio=50
,交换空间为 4GB,则允许分配的内存总量为:
16GB × 0.5 + 4GB = 12GB |
查看 CommitLimit
的值:
cat /proc/meminfo | grep -E "MemTotal|SwapTotal|CommitLimit" |
vm.overcommit_ratio
仅在vm.overcommit_memory=2
时生效。在其他模式下(vm.overcommit_memory=0
或1
),vm.overcommit_ratio
不会起作用。
vm.overcommit_kbytes
直接指定可 Overcommit 的最大内存大小 (部分新内核支持)。
vfs_cache_pressure
VFS(Virtual File System) 是 Linux 内核中的一个抽象层,用于支持多种文件系统(如 ext4
、XFS
、NTFS
等)。VFS 缓存主要包括:
目录项缓存(
dentry cache
) : 缓存目录项(dentry
),用于快速查找文件路径。inode 缓存 : 缓存文件的元数据(如权限、大小、时间戳等)。
VFS 缓存可以显著提高文件系统的访问速度,因为访问缓存中的数据比从磁盘读取要快得多。
vm.vfs_cache_pressure
控制 内核回收 VFS(Virtual File System)缓存的倾向 。取值范围包括:
值 | 行为 | 适用场景 |
---|---|---|
0-50 |
降低 VFS 缓存回收率,更倾向于保留 dentry/inode 缓存- 更多 VFS 缓存,加速文件系统访问,但可能会导致 Swap 增加。 |
适合 大量文件操作(NFS 服务器、文件服务器) |
100 |
默认值,平衡回收 VFS 缓存与 Page Cache | 适用于 通用服务器 |
>100 |
更积极回收 VFS 缓存,更快释放 inode/dentry 资源 - 减少 VFS 缓存,腾出更多内存给其他任务,但可能会导致频繁的 I/O 操作,降低文件访问效率。 |
适合 低内存服务器 |
使用以下命令可以查看 VFS 缓存占用
cat /proc/meminfo | grep -E "Cached|Dirty|Writeback" |
compact_memory
/proc/sys/vm/compact_memory
是一个 Linux 内核的内存调优参数,用于 触发内存压缩操作 。在内存碎片化较严重的情况下,调用此参数可以 强制内核进行内存压缩 ,使得内存中的空闲区域变得更加连续,从而提高系统的内存使用效率。
内存压缩是指将不再使用的内存区域合并或回收,目的是减少内存的碎片化,避免内存浪费,并且为系统中的其他进程提供更多可用的内存。
Linux 内核会自动处理内存碎片化问题,但在以下情况中,可以手动触发内存压缩:
- 内存碎片化严重 :系统在长期运行或高负载的情况下可能导致内存碎片化,手动触发内存压缩可以解决这个问题。
- 内存紧张 :在内存不足或交换空间使用较多时,可以通过压缩内存来释放更多可用内存,减少对交换空间的依赖。
若要触发内存压缩,可以写入 1
到 /proc/sys/vm/compact_memory
:
echo 1 > /proc/sys/vm/compact_memory |
这会触发内核进行内存压缩,尝试减少内存碎片化。系统会尝试将空闲内存区域合并,并释放不再使用的内存块。
OOM
Linux OOM(Out Of Memory) 是指 Linux 内核检测到系统内存耗尽 时触发的机制。当可用内存不足且无法通过 回收缓存 或 交换内存 释放更多资源时,Linux 内核会启动 OOM-Killer(OOM 杀手),选择并杀死某些进程,以释放内存,使系统继续运行。
OOM 主要发生在以下情况下:
- 物理内存不足 且 swap(交换分区)空间也耗尽 。
- 进程请求的内存超过系统可以提供的可用内存(例如
malloc()
失败) 。 - 某个进程使用了过多内存,导致其他进程无法正常运行(通常称为
内存泄漏
) 。
OOM-Killer 工作原理
当系统内存不足时,OOM-Killer
需要决定 杀死哪个进程 以释放最多的内存,同时尽可能减少对系统稳定性的影响。它会根据 OOM 分数(oom_score) 来评估进程的优先级,选择合适的目标。
OOM Score 计算方式
Linux 通过
/proc/[PID]/oom_score
计算每个进程的 OOM 分数,决定哪个进程最适合被杀死。计算方式包括:- 进程的 实际内存使用量(包括 RSS 和 swap) 。
- 进程的 优先级(nice 值) 。
- 进程是否有 特殊权限(例如 root 用户的进程通常优先级较低,不会被轻易杀死) 。
- 进程是否 手动调整了 OOM 权重(
oom_score_adj
) 。
查看进程的 OOM Score:
cat /proc/$(pgrep -f <进程名>)/oom_score
调整进程的 OOM Score
可以通过
/proc/[PID]/oom_score_adj
影响 OOM-Killer 的决策:echo -1000 > /proc/$(pgrep -f <进程名>)/oom_score_adj # 降低 OOM 优先级
echo 1000 > /proc/$(pgrep -f <进程名>)/oom_score_adj # 增加 OOM 优先级-1000
: 表示 永不杀死 该进程(适用于重要进程,如sshd
)。1000
: 表示 更容易被杀死 。
oom_dump_tasks
参数/proc/sys/vm/oom_dump_tasks
控制 当 OOM-Killer 触发时,是否记录被终止的进程信息。该参数的作用是 方便系统管理员分析 OOM 发生时的内存使用情况,帮助排查问题 。- 默认值: 1(启用) 。当发生 OOM 时,内核会记录 所有进程的内存使用信息 到系统日志。
- 禁用(0) : 发生 OOM 时,不会记录进程信息,日志会更简洁,但不利于排查问题。
oom_kill_allocating_task
参数/proc/sys/vm/oom_kill_allocating_task
控制 OOM Killer 是否优先杀死正在申请内存的进程(即导致 OOM 的那个进程) 。0(默认值)
:OOM Killer 按 OOM 评分选择要杀死的进程,不一定是触发 OOM 的进程。1
:直接杀死 触发 OOM 事件的进程(即当前正在申请内存但失败的进程) 。