在高负载服务器或者嵌入式系统上,我们经常会遇到系统“卡死”或者“假死”的情况——CPU 并没有被完全占满,I/O 并不高,但系统就是不响应。这类问题,很多时候与内存管理策略密切相关。这里我们重点解析 Linux 内核的内存压力管理机制,并讲解几个关键调优参数:
vm.min_free_kbytesvm.extra_free_kbytesvm.dirty_expire_centisecs
一、Linux 为什么会在高内存压力下挂死
Linux 内核管理内存时,会尽量保持系统有一定量的“自由页(free pages)”。当内存使用接近饱和时,内核会启动 页面回收机制(page reclaim),释放缓存、回写脏页,保证内核和用户态程序的正常运行。
如果系统缺少足够的可用内存,可能出现以下情况:
进程进入 D 状态(不可中断睡眠)进程等待 I/O 或者等待内核回收内存时阻塞,长时间无法唤醒。
OOM(Out-Of-Memory)杀手启动系统找不到足够内存分配给新请求,就会杀掉部分进程。
系统卡死内核尝试回收内存的同时,大量进程阻塞,用户体验上表现为假死。
高内存压力下,系统挂死往往不是 CPU 问题,而是内存管理策略不合理导致内核无法及时回收或调度。
二、三个关键内核参数的作用
1. vm.min_free_kbytes
2. vm.extra_free_kbytes
3. vm.dirty_expire_centisecs
三、如何修改这些参数
临时修改(重启后失效)
# 设置最小自由内存
echo 65536 > /proc/sys/vm/min_free_kbytes# 设置额外自由内存
echo 16384 > /proc/sys/vm/extra_free_kbytes# 设置脏页写回时间(30 秒)
echo 3000 > /proc/sys/vm/dirty_expire_centisecs
永久修改(重启后生效)
编辑 /etc/sysctl.conf,加入:
vm.min_free_kbytes = 65536vm.extra_free_kbytes = 16384vm.dirty_expire_centisecs = 3000
然后执行:
⚠️ 注意:调整这些参数需要结合系统内存大小和负载特性,否则可能出现浪费或性能下降。
四、调优策略与实践经验
监控内存状态
重点关注 MemFree、Buffers、Cached 和 Dirty 页。
逐步调整
先提高 min_free_kbytes,确保内核在高负载下仍有自由内存。
根据 I/O 压力调整 dirty_expire_centisecs,避免大量脏页堆积。
对突发内存分配,可适当增加 extra_free_kbytes。
结合应用调优对于数据库、大规模缓存或大内存占用程序,可以在应用层控制内存消耗,避免内核压力过大。
高内存系统注意 NUMA多节点系统下,min_free 和 extra_free 对每个 NUMA 节点生效,需按节点分配。
五、总结
高内存压力导致 Linux 系统挂死,本质是内核内存管理策略和应用内存行为不匹配。合理调节以下参数可以改善系统稳定性:
| | |
|---|
| | |
| | |
| vm.dirty_expire_centisecs | | |
调优原则:先保证系统稳定,再追求性能。在高负载服务器或嵌入式系统中,合理配置内核内存参数,是防止系统“卡死”的基础手段。