如何优化和调整Linux系统的内存使用以提高性能

来源:中国站长站作者:广州SEO公司头衔:草根站长
导读:本期聚焦于小伙伴创作的《如何优化和调整Linux系统的内存使用以提高性能》,敬请观看详情。服务器跑着跑着就卡死,用free一看内存明明还有剩却被大量占用,这类现象往往不是硬件不够而是内存策略没调好。Linux会把不常访问的页缓存起来加速读写,但这部分可回收内存常被误判为已用。通过调整vm.swappiness控制换出倾向、用cgroup限制异常进程、理解oom_killer的打分逻辑,能让系统在高负载下仍保持响应。本文从监控命令入手,说明缓存与匿名页的区别,给出sysctl与systemd配置示例,并提醒不要盲目关swap,否则反而易触发直接回收导致延迟尖刺。

Linux系统的内存性能问题通常不在物理容量本身,而在内核如何分配、回收和换出页面。理解这些机制后,我们可以通过参数调整和监控手段显著降低延迟、避免卡顿。下面先介绍基础概念,再给出具体优化做法。

如何优化和调整Linux系统的内存使用以提高性能

一、Linux内存分配与回收的基本原理

Linux内核将物理内存划分为多个区域,其中大部分用户进程使用的内存分为匿名页(anonymous pages,如堆、栈)和文件缓存页(page cache,如读取文件后的缓存)。文件缓存页在内存紧张时可以直接释放,因为磁盘上有副本;匿名页若未映射到文件,则必须写入swap才能回收。这种区分决定了调优的核心思路:尽量保留匿名页、合理释放文件缓存。

内核通过kswapd后台线程在内存水位低于阈值时异步回收,而当分配请求到来却发现空闲内存不足时,会触发直接回收(direct reclaim),此时当前进程被阻塞,造成明显的延迟。另一个关键组件是oom_killer,当系统实在无法回收出内存时,它会根据每个进程的oom_score选择得分最高的进程杀掉以保住系统。很多误杀问题的根源,就是对打分规则不了解。

1.1 查看当前内存真实使用情况

新手常只看free -m的used列,其实应该关注available列。available估算了可回收的缓存加上空闲内存,更能反映压力。我们可以用下面命令观察:

# 查看内存概览,重点看available
free -h

# 查看详细内存组成与回收状态
cat /proc/meminfo

# 观察哪些进程占用匿名内存最多
ps -eo pid,comm,vsz,rss,oom_score | sort -k5 -nr | head

上述输出中,RSS是实际物理占用,VSZ是虚拟大小。oom_score由内核计算,数值越大越容易被杀。我们可以写个简单脚本定期记录,定位泄漏源。

二、通过sysctl调整交换与回收行为

最常用的参数是vm.swappiness,取值范围0到100,表示内核倾向于换出匿名页的程度。默认值通常是60,对桌面尚可,但对延迟敏感的服务端往往偏高。将其降到10或更低,可以让内核优先回收文件缓存,减少swap写入带来的磁盘IO。

但要注意,设为0并不代表禁用swap,只是极端情况下才换出。完全关闭swap分区反而危险:当内存真正耗尽,内核无法换出匿名页,直接回收失败后会更快触发oom_killer。因此建议保留swap但调低swappiness,并配合vm.vfs_cache_pressure调整目录项缓存回收优先级。

2.1 临时与永久修改参数

临时修改可用sysctl命令,重启失效;永久修改写入/etc/sysctl.conf或使用systemd的sysctl服务。示例如下:

# 临时将swappiness设为10
sysctl -w vm.swappiness=10

# 临时提高目录缓存回收倾向(默认100,设大表示更积极回收dentry/inode)
sysctl -w vm.vfs_cache_pressure=150

# 永久生效,编辑/etc/sysctl.d/99-memory.conf
cat > /etc/sysctl.d/99-memory.conf <<'EOF'
vm.swappiness=10
vm.vfs_cache_pressure=150
vm.min_free_kbytes=65536
EOF

# 加载配置
sysctl --system

vm.min_free_kbytes预留少量内存给内核自己用,避免突发分配时直接回收。设置过大浪费内存,过小则效果不明显,一般按总内存的1%到3%取。

三、使用cgroup限制异常进程内存

如果某服务有内存泄漏倾向,与其等它拖垮整机,不如用cgroup v2把它框住。cgroup能限制一组进程的最大内存,超出后触发该组的oom而非全局oom。下面以systemd单元为例,限制某个服务最多用2G。

# 在systemd service文件中添加
[Service]
MemoryMax=2G
MemoryHigh=1.5G
TasksMax=512

其中MemoryHigh是软上限,超过后会积极回收;MemoryMax是硬上限,突破即杀进程。这样即便程序bug导致膨胀,也不会影响同机其他业务。如果是非systemd场景,可直接写cgroupfs:

# 创建cgroup并限制
mkdir /sys/fs/cgroup/mysvc
echo 2147483648 > /sys/fs/cgroup/mysvc/memory.max
echo $$ > /sys/fs/cgroup/mysvc/cgroup.procs
# 之后该shell及子进程受限于2G

这种隔离比调整全局参数更精准,也是容器技术的底层基础。生产环境应优先用cgroup而非依赖oom_killer全局兜底。

四、避坑与监控建议

一个常见误区是看到swap被用了一点就认为内存不足,其实那可能是系统闲置时kswapd换出的冷数据。只要si/so(swap in/out)在sar或vmstat里长期为0,就不用紧张。另一个坑是过度依赖drop_caches手动清缓存,这只会短暂释放,还可能导致后续读盘变慢,不如交给内核自动管理。

监控上建议部署node_exporter配合Grafana,重点看node_memory_MemAvailable_bytes、swap_io趋势和oom事件日志。当available低于总内存10%并持续,就该排查泄漏而非简单重启。调优是持续过程,结合业务峰值压测才能找到合适参数。

4.1 简单监控脚本示例

下面脚本每分钟记录一次可用内存与swap使用,便于回溯:

#!/bin/bash
while true; do
  avail=$(awk '/MemAvailable/{print $2}' /proc/meminfo)
  swap=$(awk '/SwapTotal/{t=$2} /SwapFree/{f=$2} END{print t-f}' /proc/meminfo)
  date=$(date '+%F %T')
  echo "$date avail_kb=$avail swap_used_kb=$swap" >> /var/log/mem_mon.log
  sleep 60
done

通过该日志能清楚看到内存拐点,配合前文sysctl与cgroup手段,基本可让Linux在有限硬件下维持稳定高性能。

Linux内存管理swap调优oom_killer修改时间:2026-08-06 04:09:31

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。