Speicherfressprogramme blockieren das System


3

Ich habe das folgende Problem: Ein Programm hat einen Fehler wie den folgenden

int main() {
  for(;;) {
    char *p = (char*)std::malloc(1024);
    std::memset(p, 1, 1024);
  }
}

Und es reserviert so lange Speicher, bis mein System die Seiten anderer Anwendungen zugunsten dieses Programms austauscht und ich auf der Box nichts mehr tun kann. Ich habe dieses Problem mehrmals mit verschiedenen Anwendungen getroffen (heute war es mit Moonlight 2 Beta in Firefox). Ich denke, das Problem ist, dass das Programm dazu führt, dass der Speicher eines anderen Programms ausgelagert wird und daher mehr physischen Speicher benötigt.

Natürlich habe ich mir ulimit angeschaut und zwei Einstellungen gefunden

-mDie maximale Größe
-vder residenten Gruppe ist die Größe des virtuellen Speichers

Ich habe gelesen, dass der erste die gesamte physische Speichergröße angibt, die der Prozess auf einmal verwenden kann. Für mich scheint dies sinnvoller zu sein als die gesamte Größe des virtuellen Speichers, da er möglicherweise gemeinsam genutzt wird und überhaupt keine Bedeutung hat, da er ohnehin ausgetauscht wird. Also habe ich das Folgende zu meinem hinzugefügt, .bashrcnachdem ich mir die gewohnten Resident-Set-Größen mit angesehen hatte top, die für eine gewohnte Firefox-Sitzung bis zu etwa 120 MB reichen.

# limit usage to 256MB physical memory out of 1GB
ulimit -m 262144

Aber nach meinem obigen Test Schnipsel einsetzen, noch Brough mein System nach unten, und ich musste etwa 5 Minuten warten , bis das Terminal meine erkannten ^CTaste drückt. Wenn ich in den ersten Sekunden nicht reagiere, kann ich in diesen Situationen normalerweise nur die Reset-Taste drücken, die mir nicht gefällt. Hat also jemand eine Strategie, wie man das löst? Warum funktioniert die körperliche Begrenzung nicht? Es scheint mir, dass auf diese Weise andere Anwendungen noch genügend physisches Gedächtnis haben sollten, um vernünftig zu reagieren.

Antworten:


1

Hast du es mit der -vFlagge versucht ?

Der residente Arbeitssatz wird durch die maximale Speichermenge definiert, die vor dem Auslagern als Arbeitssatz im RAM gespeichert wird. Somit wird die Gesamtmenge des Speichers einschließlich der ausgetauschten Teile des Arbeitssatzes nicht begrenzt. Die -vFlagge sollte den Job machen.

VIRTUAL MEMORY SIZE (Größe des virtuellen Speichers): Die nützlichste der speicherbezogenen Einschränkungen, da alle Arten von Speicher enthalten sind, einschließlich Stapel-, Heap- und Speicherzuordnungsdateien. Versuche, Speicher zuzuweisen, der diesen Grenzwert überschreitet, schlagen mit einem Speicherfehler fehl.

Es ist ziemlich erstaunlich, dass die Ressourcen im Netz, die dies im Detail beschreiben, nicht wirklich leicht zu finden sind! Ich habe das Experiment auf meiner Linux-Box gemacht.

Es hört mit Ausnahme mit auf

  ulimit -v 100000

und nicht mit der -mFlagge. Das einzige, was mich überrascht hat, ist die Ausnahme:

segmentation fault

Ich hätte erwartet, out of memory.


3
malloc () löst keine Ausnahme aus, gibt aber Null zurück. Dann wird der Code versuchen, dort zu schreiben ... also sein Segmentierungsfehler.
Liori

Allerdings frage ich mich, warum mein System auch mit -m stecken bleibt. Ich dachte, dass, wenn der physische Speicher für den Prozess begrenzt ist (sein Arbeitssatz), andere Anwendungen nicht ausgelagert werden und immer noch reagieren. Das System wird jedoch trotzdem gesperrt. Warum ist das? Wenn nichts anderes hilft, verwende ich virtuellen Speicher, auch wenn dies viele Dinge beinhaltet, die nicht zum Herunterfahren der Maschine
beitragen

@ Liori, guter Punkt, dumm, ich denke, ich mache zu viel C ++ ... :-)
Jdehaan

@litb Ich meinte, dass mit -mder Menge des physischen Speichers begrenzt ist, aber nicht die virtuelle. Der Prozess wird also vertauscht. Ich habe gelesen, dass nicht alle Varianten von Shell / Linux unterstützt werden -m. Sie können überprüfen, was tatsächlich mit ulimit -aoder mit ulimit -m(ohne Parameter) eingestellt ist
Jdehaan

1

Ich denke, ulimit Implementierung saugt zufällig auf fast jedem Betriebssystem. Ich benutze ulimit -S -v unter Linux seit sechs Jahren. Sechs! Und es scheint, dass einige Kernel es nicht mehr unterstützen. Ich habe einen Mac und OS X 10.6 unterstützt ihn nicht. Ich habe es auch mit -m versucht. In meinem alten Desktop mit Ubuntu 9.04 funktioniert ulimit -S -v einwandfrei.

In der Tat bin ich auf der Suche nach einer echten Lösung dafür. Ich kann einfach nicht glauben, dass Leute in Apple beispielsweise zulassen, dass ihr Programm im Speicher verrückt wird.


0

Klassisches Speicherleck. Ich fürchte, Sie müssen die betreffende Anwendung bugfixen, das Betriebssystem kann nicht viel. Alles, was das Betriebssystem tun könnte, ist, den Speicher für eine Anwendung zu beschränken, aber dann würde die betreffende Anwendung abstürzen / segfault und möglicherweise das Betriebssystem oder zumindest xorg mitnehmen.

Sie könnten ld_preload eine andere Version von malloc und einen Thread hinzufügen, um es nach einer festgelegten Anzahl von Sekunden zu befreien. Ich bezweifle jedoch, dass es funktionieren würde ...

Sie benötigen dieses Tut: http://lattice.umiacs.umd.edu/files/functions_tr.pdf

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.