有没有办法让OOM杀手工作并阻止Linux冻结?我一直在运行Java和C#应用程序,其中通常使用分配的任何内存,并且(如果我正确理解它们)过度使用会导致计算机冻结。现在,作为临时解决方案,我补充道,
vm.overcommit_memory = 2
vm.overcommit_ratio = 10
到/etc/sysctl.conf。
对任何能够解释为什么现有的OOM杀手无法以保证方式正常运行的人都会感到荣幸,只要内核耗尽“真实”内存,就会终止进程。
编辑 - 很多回应都与迈克尔有关“如果你遇到与OOM杀手相关的问题,那么你可能需要修复导致你内存不足的任何问题”。我不认为这是正确的解决方案。总会有应用程序出现错误,我想调整内核,这样我的整个系统就不会冻结。鉴于我目前的技术理解,这似乎不应该是不可能的。
答案 0 :(得分:3)
下面是我写的一个非常基本的perl脚本。通过一些调整,它可能是有用的。您只需要将路径更改为使用Java或C#的任何进程的路径。您可以更改我用于重启命令的kill命令。 当然为了避免手动输入perl memusage.pl,您可以将其放入crontab文件中以自动运行。您也可以使用perl memusage.pl> log.txt将其输出保存到日志文件中。对不起,如果它没有真正的帮助,但我喝一杯咖啡时很无聊。 :-D干杯
#!/usr/bin/perl -w
# Checks available memory usage and calculates size in MB
# If free memory is below your minimum level specified, then
# the script will attempt to close the troublesome processes down
# that you specify. If it can't, it will issue a -9 KILL signal.
#
# Uses external commands (cat and pidof)
#
# Cheers, insertable
our $memmin = 50;
our @procs = qw(/usr/bin/firefox /usr/local/sbin/apache2);
sub killProcs
{
use vars qw(@procs);
my @pids = ();
foreach $proc (@procs)
{
my $filename=substr($proc, rindex($proc,"/")+1,length($proc)-rindex($proc,"/")-1);
my $pid = `pidof $filename`;
chop($pid);
my @pid = split(/ /,$pid);
push @pids, $pid[0];
}
foreach $pid (@pids)
{
#try to kill process normall first
system("kill -15 " . $pid);
print "Killing " . $pid . "\n";
sleep 1;
if (-e "/proc/$pid")
{
print $pid . " is still alive! Issuing a -9 KILL...\n";
system("kill -9 " + $pid);
print "Done.\n";
} else {
print "Looks like " . $pid . " is dead\n";
}
}
print "Successfully finished destroying memory-hogging processes!\n";
exit(0);
}
sub checkMem
{
use vars qw($memmin);
my ($free) = $_[0];
if ($free > $memmin)
{
print "Memory usage is OK\n";
exit(0);
} else {
killProcs();
}
}
sub main
{
my $meminfo = `cat /proc/meminfo`;
chop($meminfo);
my @meminfo = split(/\n/,$meminfo);
foreach my $line (@meminfo)
{
if ($line =~ /^MemFree:\s+(.+)\skB$/)
{
my $free = ($1 / 1024);
&checkMem($free);
}
}
}
main();
答案 1 :(得分:1)
如果您的进程的oom_adj设置为-17,则不会考虑杀死,尽管我怀疑这是问题所在。
cat /proc/<pid>/oom_adj
将告诉您进程的值oom_adj。
答案 2 :(得分:0)
我编写了一个简单的脚本,用于在发布时设置 OOM 分数。所有子进程都会继承这个分数。
#!/usr/bin/env sh
if [ -z "$1" ] || [ -z "$2" ]; then
echo "Usage: $(basename "$0") oom_score_adj command [args]..."
echo " oom_score_adj A score between -1000 and 1000, bigger gets killed first"
echo " command The command to run"
echo " [args] Optional args for the command to run"
exit 1
fi
set -eux
echo $1 > /proc/self/oom_score_adj
shift
exec $@
脚本将本地进程的分数设置为提供的第一个参数。这可以是 -1000 到 1000 之间的任何值,其中 1000 最有可能首先被杀死。然后将其余参数作为带有 args 的命令执行,替换当前进程。
答案 3 :(得分:-1)
我不得不说防止OOM冻结的最好方法是不要耗尽虚拟内存。如果你经常耗尽虚拟内存或接近虚拟内存,那么你就会遇到更大的问题。
大多数任务都不能很好地处理失败的内存分配,因此容易崩溃或丢失数据。耗尽虚拟内存(使用或不使用overcommit)将导致某些分配失败。这通常很糟糕。
此外,在你的操作系统耗尽虚拟内存之前,它会开始做坏事,比如从常用的共享库中丢弃页面,这可能会让性能变得很糟糕,因为它们必须经常被拉回来,这非常糟糕对于吞吐量。
我的建议:
也可能
如果这对您的用例有帮助。
大多数多进程服务器运行可配置(最大)数量的进程,因此您通常可以向下调整它。多线程服务器通常允许您在内部配置用于缓冲区等的内存量。
答案 4 :(得分:-1)
首先,你怎么能确定冻结与OOM杀手有关?我在现场有一个系统网络,我不会经常冻结,这似乎与OOM无关(我们的应用在内存使用方面非常稳定)。它可能是别的吗?有没有涉及有趣的硬件?有不稳定的司机?高性能视频?
即使OOM杀手参与并且工作,你仍然会有问题,因为你认为正在运行的东西现在已经死了,谁知道它留下了什么样的混乱。
真的,如果您遇到与OOM杀手相关的问题,那么您可能需要修复导致内存不足的任何问题。
答案 5 :(得分:-1)
我发现修复稳定性问题主要依赖于准确识别根本原因。不幸的是,这需要能够看到问题发生时发生的事情,这是尝试启动各种监控程序的非常糟糕的时间。
我有时觉得有用的一件事是在启动时启动一个小的监控脚本,它会记录各种有趣的数字并快照正在运行的进程。然后,如果发生崩溃,我可以在崩溃前查看情况。我有时发现直觉对根本原因是非常错误的。不幸的是,那个脚本已经过时了,或者我给了一个链接。