2010-01-24 4 views
21

Gibt es eine Möglichkeit, den OOM-Killer zu aktivieren und zu verhindern, dass Linux einfriert? Ich habe Java- und C# -Anwendungen ausgeführt, in denen normalerweise allokierter Speicher verwendet wird, und (wenn ich sie richtig verstehe) verursachen Überkommandos das Einfrieren der Maschine. Als vorübergehende Lösung fügte ich jetztWas ist der beste Weg, zu verhindern, dass nicht genügend Arbeitsspeicher (OOM) auf Linux einfriert?

zu /etc/sysctl.conf hinzu.

Kudos an alle, die erklären können, warum der existierende OOM-Killer nicht in einer garantierten Weise korrekt funktionieren kann, Prozesse abtötend, wenn der Kernel keinen "echten" Speicher mehr hat.

BEARBEITEN - viele Antworten sind in Anlehnung an Michaels "Wenn Sie OOM-Killer-bezogene Probleme haben, dann müssen Sie wahrscheinlich reparieren, was Ihnen den Speicher ausschaltet". Ich denke nicht, dass dies die richtige Lösung ist. Es wird immer Apps mit Bugs geben, und ich möchte den Kernel anpassen, damit mein gesamtes System nicht einfriert. Angesichts meines derzeitigen technischen Verständnisses scheint dies nicht so zu sein, dass es unmöglich sein sollte.

+0

Um den Speicher zu begrenzen, warum sollten Sie den Overcommit nicht auf Parität beschränken? – wallyk

+1

Der OOM-Killer auf meinen Linux-Systemen scheint zu funktionieren wie geplant. Wie sicher bist du, dass du einen OOM Killerfehler hast? Warum denkst du, dass das der Grund ist? Haben Sie auch die Möglichkeit eines Problems mit dem Garbage Collector in Betracht gezogen? – dmckee

+0

@dmckee - alle anderen Anwendungen einfrieren. @ Wallyk - Was ist "Begrenzung der Überkompensierung auf Parität"? – gatoatigrado

Antwort

1

Wenn oom_adj für Ihre Prozesse auf -17 gesetzt ist, wird es nicht zum Töten berücksichtigt, obwohl ich bezweifle, dass es sich hier um das Problem handelt.

cat /proc/<pid>/oom_adj

werden Ihnen sagen, den Wert Ihres Prozesses (e) 's oom_adj.

+0

Wenn 'cat/proc//oom_adj' nicht funktioniert, benutze' cat/proc//oom_score_adj' – erm3nda

0

Ich würde sagen, der beste Weg zur Verhinderung von OOM-Einfrieren ist, dass der virtuelle Speicher nicht ausgeht. Wenn Ihnen regelmäßig der virtuelle Speicher ausgeht oder Sie sich nähern, haben Sie größere Probleme.

Die meisten Aufgaben behandeln fehlerhafte Speicherzuordnungen nicht sehr gut, so dass sie zum Absturz neigen oder Daten verlieren. Wenn Sie den virtuellen Speicher (mit oder ohne Überkomprimierung) nicht verwenden, werden einige Zuweisungen fehlschlagen. Das ist normalerweise schlecht.

Darüber hinaus, bevor Ihr Betriebssystem aus dem virtuellen Speicher ausgeht, wird es beginnen, schlechte Dinge wie das Verwerfen von Seiten aus häufig verwendeten Bibliotheken, die Leistung zu saugen, da sie oft zurückgezogen werden müssen, was sehr ist schlecht für den Durchsatz.

Meine Vorschläge:

  • mehr RAM
  • Run weniger Prozesse
  • Nehmen Sie die Prozesse Holen Sie weniger Speicher ausführen kann (Diese umfassen können Speicherverluste in ihnen Fixierung)

Und möglicherweise auch

  • Se t up mehr Swap Space

Wenn das in Ihrem Anwendungsfall hilfreich ist.

Die meisten Server mit mehreren Prozessen führen eine konfigurierbare (maximale) Anzahl von Prozessen aus, sodass Sie sie in der Regel nach unten abstimmen können. Mit Multithread-Servern können Sie in der Regel konfigurieren, wie viel Speicher intern für ihre Puffer usw. verwendet werden soll.

+1

Ich habe einen Fehler gemacht: Ich habe versucht, eine 55 GByte XML-Datei anzuzeigen. Nach einigen zehn Sekunden ist die Maschine eingefroren. Ich vermute, dass ein Teil des Problems ist, dass meine Auslagerungsdatei nicht 55 GByte groß ist. Es ist jedoch schlechtes Design, eine Benutzer-Space-Anwendung ein ganzes System lahmlegen zu lassen.IMHO, wenn ein einzelner Prozess zu viel virtuellen RAM verwendet, dann sollte der Kernel ** diesen ** Prozess töten, wodurch der virtuelle RAM frei wird und der Rest des Systems weitermachen kann. Es sollte nicht möglich sein, dass eine Benutzeranwendung das System in einen Zustand versetzt, in dem es nur einen Neustart gibt. – user1928764

4

Unten ist ein wirklich grundlegendes Perl-Skript, das ich schrieb. Mit ein wenig Feinabstimmung könnte es nützlich sein.Sie müssen nur die Pfade zu den Pfaden aller Prozesse ändern, die Java oder C# verwenden. Sie könnten die Kill-Befehle, die ich zum Neustarten von Befehlen verwendet habe, auch ändern. Natürlich, um das manuelle Eingeben von Perl memusage.pl zu vermeiden, könnten Sie es in Ihre Crontab-Datei einfügen, um automatisch zu starten. Sie können auch permemusage.pl> log.txt verwenden, um die Ausgabe in einer Protokolldatei zu speichern. Entschuldigung, wenn es nicht wirklich hilft, aber ich war gelangweilt, während ich eine Tasse Kaffee trank. :-D Cheers

#!/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(); 
+0

Nicht schlecht, aber vielleicht nicht so zuverlässig. Vielleicht würden harte ulimits funktionieren? Ich kann sie anscheinend nicht bekommen ... – gatoatigrado

+1

Sorry, aber was wolltest du mit harten ulimits machen? Denken Sie daran, dass Sie nur harte Grenzen als root setzen können. Es gibt eine extra Konfiguration in /etc/security/limits.conf, glaube ich. – user198470

1

Zunächst einmal, wie können Sie sicher sein, dass die Freezes OOM Killer verwandt sind? Ich habe ein Netzwerk von Systemen im Feld und es kommt nicht selten vor, dass die Freezes nicht mit OOM in Verbindung stehen (unsere App ist ziemlich stabil in der Speichernutzung). Könnte es etwas anderes sein? Gibt es eine interessante Hardware? Irgendwelche instabilen Treiber? Hochleistungsvideo?

Selbst wenn der OOM-Killer involviert ist und funktioniert, hat man immer noch Probleme, weil Dinge, von denen man denkt, dass sie laufen, jetzt tot sind und wer weiß, was für ein Durcheinander es hinterlassen hat.

Wirklich, wenn Sie OOM Killer-bezogene Probleme haben, dann müssen Sie wahrscheinlich reparieren, was verursacht, dass Sie nicht genügend Arbeitsspeicher haben.

+0

einmal oder zweimal, ich konnte den Systemmonitor hochziehen, bevor alles einfriert. – gatoatigrado

0

Ich habe festgestellt, dass die Behebung von Stabilitätsproblemen hauptsächlich auf der genauen Identifizierung der Ursache beruht. Leider muss man sehen können, was passiert, wenn das Problem auftritt, was ein wirklich schlechter Zeitpunkt ist, um verschiedene Überwachungsprogramme zu starten.

Eine Sache, die ich manchmal hilfreich fand, war ein kleines Überwachungsskript beim Booten zu starten, das verschiedene interessante Zahlen protokollieren und die laufenden Prozesse aufzeichnen würde. Dann konnte ich im Falle eines Unfalls die Situation kurz vor dem Absturz betrachten. Manchmal stellte ich fest, dass die Intuition mit der Ursache ziemlich falsch lag. Leider ist dieses Skript längst veraltet oder ich gebe einen Link.

Verwandte Themen