Каким образом можно предотвратить замораживание памяти (OOM) в Linux?
Есть ли способ заставить убийцу OOM работать и не замораживать Linux? Я использую приложения Java и С#, где обычно используется любая выделенная память, и (если я понимаю их правильно) чрезмерные вызовы заставляют машину замораживаться. Прямо сейчас, в качестве временного решения, я добавил:
vm.overcommit_memory = 2
vm.overcommit_ratio = 10
в/etc/sysctl.conf.
Престижность любому, кто может объяснить, почему существующий убийца OOM не может нормально функционировать в гарантированном порядке, убивая процессы, когда у ядра заканчивается "реальная" память.
РЕДАКТИРОВАТЬ - многие ответы идут по строкам Майкла, "если вы испытываете проблемы с убийцей OOM, то вам, вероятно, нужно исправить все, что заставляет вас исчерпать память". Я не думаю, что это правильное решение. Всегда будут приложения с ошибками, и я бы хотел настроить ядро, чтобы вся моя система не зависала. Учитывая мои текущие технические договоренности, это не похоже, что это должно быть невозможно.
Ответы
Ответ 1
Ниже приведено действительно базовое perl script, которое я написал. С небольшим количеством настроек он может быть полезен. Вам просто нужно изменить пути, которые у меня есть к путям любых процессов, использующих Java или С#. Вы можете изменить команды уничтожения, которые я использовал для перезапуска команд.
Конечно, чтобы избежать ввода в 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();
Ответ 2
Если ваши процессы oom_adj установлены на -17, это не будет рассматриваться для убийства, если я сомневаюсь, что здесь проблема.
cat /proc/<pid>/oom_adj
сообщит вам значение вашего процесса (ов) oom_adj.
Ответ 3
Во-первых, как вы можете быть уверены, что зависания связаны с убийцей OOM? У меня есть сеть систем в поле, и я получаю нередкие зависания, которые, похоже, не связаны с OOM (наше приложение довольно стабильно в использовании памяти). Может быть, это что-то еще? Есть ли интересное оборудование? Любые неустойчивые драйверы? Высокопроизводительное видео?
Даже если убийца OOM задействован и работает, у вас все еще будут проблемы, потому что вещи, которые, как вы думали, были запущены, теперь мертвы, и кто знает, какой беспорядок он оставил.
Действительно, если у вас возникли проблемы с убийцей OOM, тогда вам, вероятно, нужно исправить все, что может привести к выходу из памяти.
Ответ 4
Я должен сказать, что лучший способ предотвратить замораживание OOM - не исчерпывать виртуальную память. Если у вас постоянно заканчивается виртуальная память или приближается, тогда у вас больше проблем.
Большинство задач не справляются с неудачными выделениями памяти очень хорошо, поэтому имеют тенденцию к сбою или потере данных. Запуск из виртуальной памяти (с или без overcommit) приведет к сбою некоторых распределений. Обычно это плохо.
Кроме того, до того, как у вашей ОС закончится виртуальная память, она начнет делать плохие вещи, такие как отбрасывание страниц из общедоступных разделяемых библиотек, что, вероятно, приведет к сосанию производительности, поскольку их нужно часто отводить, что очень плохо для пропускной способности.
Мои предложения:
- Получить больше ram
- Запустить меньше процессов
- Сделать процессы, которые вы выполняете, использовать меньше памяти (это может включать исправление утечек памяти в них)
И возможно также
- Настройка большего пространства подкачки
Если это полезно в вашем прецеденте.
Большинство серверов с несколькими процессами запускают настраиваемое (максимальное) количество процессов, поэтому вы можете настроить его вниз. Многопоточные серверы обычно позволяют настраивать, сколько памяти использовать для своих буферов и т.д. Внутри.
Ответ 5
Я обнаружил, что проблемы с фиксированной стабильностью в основном зависят от точной идентификации основной причины. К сожалению, это требует возможности увидеть, что происходит, когда проблема возникает, что очень плохое время для запуска различных программ мониторинга.
Одна вещь, которую я иногда нашел полезной, заключалась в том, чтобы запустить небольшой мониторинг script во время загрузки, который записывал бы различные интересные номера и моментально отображал текущие процессы. Тогда, в случае крушения, я мог бы посмотреть на ситуацию перед катастрофой. Я иногда обнаружил, что интуиция была совершенно неправильной в отношении основной причины. К сожалению, этот script длинный устаревший, или я бы дал ссылку.