系统 swap 使用率过高的根源分析与解决方案:一次实战排查记录

最近在维护一台线上服务器时,突然收到监控告警:系统 swap 使用率超过 80%。作为运维人员,我深知 swap 使用率过高可能意味着内存不足,进而影响系统性能。经过一番排查和优化,最终解决了问题。今天就把这次实战经验整理成文,分享给大家。
1. 什么是 swap?为什么需要关注它?
简单来说,swap 是磁盘上的一块空间,当物理内存不足时,系统会将部分不常用的内存数据暂时移到 swap 中,从而释放物理内存供更紧急的任务使用。听起来很美好,对吧?但 swap 的读写速度远低于物理内存,频繁使用会导致系统性能下降。如果 swap 使用率持续很高,通常意味着物理内存严重不足。
2. 如何确认 swap 使用情况?
首先,我们需要确认 swap 的使用情况。使用以下命令可以快速查看:
free -h
输出示例:
total used free shared buff/cache available
Mem: 7.7G 5.2G 1.1G 456M 1.4G 1.8G
Swap: 2.0G 1.6G 416M
从输出可以看到,swap 总大小为 2GB,已使用 1.6GB,使用率确实很高。同时,物理内存可用量(available)只有 1.8GB,说明内存压力较大。
3. 分析 swap 使用率过高的根源
swap 使用率高通常有几个常见原因。我按照以下步骤逐一排查:
3.1 检查内存使用详情
使用 top 或 htop 命令查看哪些进程占用了大量内存:
top -o %MEM
按内存使用率排序后,我发现一个 Java 进程占用了近 4GB 内存,而系统总内存只有 8GB。这可能是问题的根源。
3.2 检查 swappiness 设置
swappiness 参数控制系统使用 swap 的倾向程度,范围是 0-100。值越高,越倾向于使用 swap。检查当前设置:
cat /proc/sys/vm/swappiness
输出为 60,这是一个相对较高的值,意味着系统比较“积极”地使用 swap。
3.3 检查是否有内存泄漏
使用 vmstat 观察内存变化:
vmstat 1 5
如果 si(swap in)和 so(swap out)字段持续有值,说明系统正在频繁交换数据,可能存在内存泄漏或内存不足。
4. 解决方案与优化步骤
根据排查结果,我采取了以下措施:
4.1 优化应用程序内存配置
针对那个占用大量内存的 Java 进程,我调整了 JVM 参数,限制了堆内存大小:
java -Xmx2g -Xms1g -jar myapp.jar
将最大堆内存从 4GB 降到 2GB,减轻了内存压力。
4.2 调整 swappiness 参数
将 swappiness 从 60 降到 10,减少系统使用 swap 的倾向:
echo 10 > /proc/sys/vm/swappiness
为了永久生效,编辑 /etc/sysctl.conf 文件:
echo 'vm.swappiness=10' >> /etc/sysctl.conf
4.3 清理不必要的进程和服务
使用 ps aux --sort=-%mem | head -10 找出其他内存占用高的进程,停掉了一些非必要的服务。
4.4 考虑增加物理内存
如果以上措施仍无法解决问题,可能需要考虑升级硬件,增加物理内存。这是最直接的解决方案。
5. 验证优化效果
优化后,再次使用 free -h 查看:
total used free shared buff/cache available
Mem: 7.7G 4.1G 2.8G 456M 0.8G 3.1G
Swap: 2.0G 256M 1.7G
可以看到,swap 使用率从 80% 降到了 12% 左右,物理内存可用量也增加到 3.1GB,系统性能明显改善。
6. 踩坑与总结
在这次排查过程中,我差点犯了一个错误:直接关闭 swap。虽然这能立即降低 swap 使用率,但如果物理内存不足,系统可能会因 OOM(Out Of Memory)而崩溃。所以,千万不要在没确认物理内存充足的情况下禁用 swap。
总结一下,处理 swap 使用率过高的问题,关键在于:
- 确认内存使用情况,找出占用内存大的进程
- 合理调整 swappiness 参数
- 优化应用程序内存配置
- 必要时增加物理内存
希望这篇实战经验对你有帮助。如果你也遇到了类似问题,欢迎在评论区交流讨论!


看完文章立马检查了服务器,果然swappiness设太高了👍