CentOS 7 内存占用过大导致 OOM Killer 杀掉了 Java 进程
说明
测试服务器, 有一个 Java 应用, 其进程偶尔会消失掉, 已排除人为杀死的可能
该服务器内存常年处于快被占满的状态, 怀疑是内存原因, 导致服务器主动杀死了该应用的 Java 进程
使用的命令
free -h
, 用于查看系统内存使用情况, 显示系统当前的内存使用情况,以及内存总量、已用内存、空闲内存等信息top
, 列出当前运行的进程,并显示每个进程的相关信息,如进程 ID、用户、CPU 使用率、内存使用量、进程状态等- 按
c
键显示完整 cmdline - 切换排序方式:
P
:按照 CPU 使用率高低排序。M
:按照内存使用量高低排序。T
:按照运行时间长短排序。
- 进程操作:
k
:杀死选定的进程。按下 k 后,会提示输入要杀死的进程的 PID(进程ID)。r
:修改进程的优先级。按下 r 后,会提示输入要修改优先级的进程的 PID 以及新的优先级值。
- 切换显示方式:
v
或F
:打开字段管理器,可以添加或删除显示的列。o
或O
:按照指定的字段进行排序,输入 o 后,会提示输入字段的序号进行排序。
- 查看帮助和退出:
h
:显示帮助信息,列出所有可用的快捷键。q
:退出 top 命令。
- 刷新和暂停:
Space
:刷新 top 的显示。S
:切换安全模式,延迟显示,适用于终端速度慢的情况。1
:显示所有 CPU 的利用率。
- 按
经过一番了解, 得知 Linux 服务器有一个叫做 OOM Killer
的机制, 大致就是该机制会监控那些占用内存过大(尤其是瞬间占用内存很快的进程), 然后防止内存耗尽而自动把该进程杀掉
通过执行 grep java /var/log/messages | grep "Out of memory"
发现最近几日都有 Java 进程被杀掉的日志记录, 但是无法确定对应 PID 是否是我们的应用, 所以需要验证
#!/bin/bash
for proc in $(find /proc -maxdepth 1 -regex '/proc/[0-9]+'); do
printf "%2d %5d %s\n" "$(cat $proc/oom_score)" "$(basename $proc)" "$(cat $proc/cmdline | tr '\0' ' ')"
done 2>/dev/null | sort -nr | head -n 10
上述是一个查看 OOM Killer 给各个进程打分的脚本, 执行该脚本即可找出最有可能被杀掉的进程, 从左到右分别是 score pid cmdline, 分数越高被杀的优先级越高
其中第一个是一个 Java 进程 overview.jar, 其 pid 为 91917, 得分为 165, 第二名的得分为 84
自己写一个新程序, 每次调用接口都会多占用 8M 内存, 多次调用, 直至系统触发 OOM Killer
private static final Map<String, List<Long>> MAP = new HashMap<>();
@RequestMapping("test")
public Result<Object> test() {
MAP.put(IdKit.uuid(), new ArrayList<>(1024 * 1024));
return Result.ok();
}
经过测试, 果然 overview.jar 程序被杀死了, 且在 /var/log/messages 里面多了如下日志
Jun 27 10:45:27 2-03cs01 kernel: Out of memory: Kill process 91917 (java) score 165 or sacrifice child
解决办法就是换机器
原文地址:https://blog.csdn.net/mrathena/article/details/140013111
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!