有没有办法使OOM杀手工作,并防止Linux冻结? 我一直在运行Java和C#应用程序,其中通常使用任何内存分配,并且(如果我正确理解),overcommits导致机器冻结。 眼下,作为临时解决scheme,我补充道,
vm.overcommit_memory = 2 vm.overcommit_ratio = 10
到/etc/sysctl.conf。
任何人都可以解释为什么现有的OOM杀手无法以保证的方式正确运行,只要内核用完“真实”的内存就会终止进程。
编辑 – 许多回应是迈克尔的“如果你遇到与OOM杀手相关的问题,那么你可能需要解决任何导致你用尽内存”。 我不认为这是正确的解决scheme。 总是会有bug的应用程序,我想调整内核,所以我的整个系统不冻结。 鉴于我目前的技术理解,这似乎不应该是不可能的。
下面是我写的一个非常基本的Perl脚本。 稍微调整一下可能会有用。 您只需要将所有路径更改为使用Java或C#的任何进程的路径。 你也可以改变我用来重新启动命令的kill命令。 当然为了避免手动输入perl memusage.pl,你可以把它放到你的crontab文件中来自动运行。 您也可以使用perl memusage.pl> log.txt将其输出保存到日志文件中。 对不起,如果它不是真的有帮助,但喝一杯咖啡,我很无聊。 :-干杯
#!/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();
如果你的进程的oom_adj被设置为-17它不会被认为是杀死了,我怀疑这是问题在这里。
cat /proc/<pid>/oom_adj
会告诉你你的进程的价值oom_adj。
首先,你如何确定冻结与OOM杀手有关? 我在这个领域有一个系统的网络,并且我并不经常冻结,这似乎不是OOM相关的(我们的应用程序在内存使用上相当稳定)。 难道是别的吗? 是否有涉及有趣的硬件? 任何不稳定的司机 高性能视频?
即使OOM杀手也参与其中并且工作,你仍然有问题,因为你认为正在运行的东西现在已经死了,谁知道它留下了什么样的混乱。
真的,如果您遇到与OOM杀手相关的问题,那么您可能需要解决导致您耗尽内存的任何问题。
我不得不说,防止OOM冻结的最好方法是不要耗尽虚拟内存。 如果你经常用完虚拟内存,或者越来越近,那么你就有更大的问题。
大多数任务不处理失败的内存分配,所以往往会崩溃或丢失数据。 用完虚拟内存(有或没有overcommit)会导致一些分配失败。 这通常是不好的。
而且,在你的操作系统用完虚拟内存之前,它会开始做一些糟糕的事情,比如丢弃常用共享库中的页面,这很可能使性能变得糟糕,因为它们必须经常被拉回来,这对吞吐量是非常不利的。
我的建议:
也可能
如果这对您的使用情况有帮助。
大多数多进程服务器运行一个可配置(最多)的进程数量,所以通常可以向下调整它。 多线程服务器通常允许您配置在内部为其缓冲区等使用多少内存。
我发现修复稳定性问题主要依赖于准确地确定根本原因。 不幸的是,这需要能够看到发生问题时发生了什么,这是尝试启动各种监控程序的真正糟糕的时刻。
有时候我发现有用的一件事是在启动时启动一个小监控脚本,记录各种有趣的数字并快照正在运行的进程。 那么,在发生事故的时候,我可以在事故发生之前看一下情况。 有时我发现直觉对于根本原因是错误的。 不幸的是,这个脚本已经过时了,或者我会给出一个链接。