一、什么是 OOM?为什么会发生?

OOM 全称 “Out Of Memory”,即内存耗尽。当 Linux 系统内存不足以分配给新进程或现有进程时,内核会触发 OOM Killer,强制终止某个进程以释放内存。

火山引擎服务器新用户特惠建议根据自己需求选择,普通展示网站客户量小的运存2g即可,更大需求量建议选择更高配置的云服务器

常见原因:

  • 系统运行了内存密集型程序(如数据库、大数据处理工具);

  • 缓存 / 缓冲区占用过高(Linux 会主动用空闲内存做缓存,导致 “看似内存不足”);

  • 进程内存泄漏(程序运行时持续占用内存,不释放);

  • 配置错误(如 Java 应用分配内存过大,超过系统实际可用内存)。
    二、OOM 发生时的典型症状

  • 系统突然卡顿、鼠标 / 键盘响应延迟;

  • 应用程序崩溃(报错 “Killed” 或 “Out of memory”);

  • 系统日志中出现类似信息:Out of memory: Kill process 1234 (java) score 950 or sacrifice child;

  • free -m 显示 “available” 内存接近 0,buff/cache 却很高。
    三、快速排查与处理步骤
    Step 1:确认 OOM 原因,查看系统日志

OOM Killer 终止进程后会在系统日志中留下线索,先定位关键信息:

查看最近的OOM相关日志(CentOS/RHEL)grep -i oom /var/log/messages

Ubuntu/Debian系统日志位置不同,可执行:dmesg | grep -i oom

日志中关键信息:
Out of memory: Kill process (<进程名>) …
(记下 PID 和进程名,比如 PID=1234,进程名 = java)
Step 2:用工具快速定位高内存进程

根据日志中的 PID,用工具查看进程内存占用情况:
方法 1:htop(推荐新手,界面友好)

安装htop(若未安装):sudo apt install htop 或 yum install htophtop

  • 操作:按 F6 选择 “% MEM” 排序(按内存占用从高到低),直接查看内存占用最高的进程;
  • 注意:如果进程名是 “XX 服务”,需判断是否为必要进程(如系统核心服务或业务进程)。
    方法 2:top(基础命令)

top

  • 操作:按 M 键按内存占用排序,按 P 按 CPU 占用排序,按 q 退出。
    方法 3:快速筛选内存高的进程

ps -aux --sort=-%mem | head # 按内存占用排序,取前10个进程
Step 3:终止不必要的进程

如果确认是非关键进程(如临时运行的脚本、测试工具),直接 kill 掉:

先尝试优雅终止(正常退出)kill # 替换为目标进程ID# 若进程无响应,强制终止(需谨慎,避免数据丢失)kill -9

⚠️ 注意:

  • 不要直接 kill 系统核心进程(如 systemd、init、ssh 服务),否则系统可能崩溃;
  • 终止前确认进程用途,可用 ps -p -o comm= 查看进程名,或 cat /proc//cmdline 查看完整命令。
    Step 4:释放系统缓存(若缓存占用过高)

Linux 会用空闲内存做缓存(如文件缓存、目录缓存),这些缓存可安全释放而不影响性能。
操作步骤:

  1. 先同步内存数据到磁盘(防止缓存数据丢失):
    sync # 同步所有数据到磁盘

  2. 释放缓存(分 3 种场景):

释放pagecache(文件缓存)echo 1 > /proc/sys/vm/drop_caches

释放dentry和inode缓存(目录/文件元数据)echo 2 > /proc/sys/vm/drop_caches

释放全部缓存(pagecache+目录缓存)echo 3 > /proc/sys/vm/drop_caches

原理:/proc/sys/vm/drop_caches 数值含义:1=pagecache,2=dentry+inode,3 = 全部。
Step 5:排查根本原因(长期解决)

如果频繁 OOM,需排查是否存在内存泄漏或配置错误:
场景 1:进程内存泄漏

  • 若为 Java 应用:用 jstat -gc 查看 GC 情况,jmap -heap 看堆内存分配是否异常;

  • 若为 Python/Go 程序:用 valgrind(C/C++)或 tracemalloc(Python)工具定位泄漏代码。
    场景 2:配置参数过大

  • 检查应用内存配置:如 Java -Xmx(最大堆内存)是否超过系统实际可用内存;

  • 数据库(MySQL/PostgreSQL):检查缓存参数(如innodb_buffer_pool_size)是否设置过高。
    场景 3:系统参数优化

若需临时提高内存上限,可调整内核参数(临时生效):

允许系统过度使用内存(可能导致更多OOM)echo “vm.overcommit_memory=1” >> /etc/sysctl.conf

sysctl -p # 生效

⚠️ 注意:vm.overcommit_memory=1 会让系统允许程序 “过度申请” 内存,可能掩盖真实问题,需配合应用内存调优使用。
四、预防 OOM 的日常操作

  1. 定期监控内存:用 free -m 或 nmon(监控工具)观察内存趋势;
  2. 限制关键进程内存:通过 cgroup 或 systemd 限制单个进程的内存上限(如 systemd-run --scope --slice=memory.slice --user.slice=100M java);
  3. 及时重启服务:若应用长期运行,定期重启服务避免内存泄漏累积;
  4. 升级硬件:若业务增长快,直接扩容服务器内存是最根本解决办法。
    五、总结:新手 OOM 处理流程图

OOM发生 → 查日志→ 定位进程 → 终止非关键进程 → 释放缓存(sync+drop_caches) → 排查内存泄漏/配置 → 优化参数/扩容
六、常见问题 Q&A

Q:为什么free -m显示 “available” 很低,但进程还是说 OOM?
A:Linux 缓存(buff/cache)会被算作 “已用内存”,但实际可用时可释放。此时执行 free -m 看到的 “可用”=“free”+“buff/cache”,无需过度担心,可通过释放缓存解决。

Q:kill -9 会导致数据丢失吗?
A:仅当进程正在操作未写入磁盘的数据时可能丢失。终止前先执行 sync 可避免大部分风险。

Q:系统重启后 OOM 问题依旧?
A:大概率是配置错误(如 Java 内存过大)或硬件不足,需检查应用参数或联系运维扩容。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐