Behandeln Sie Speicherprobleme?

9

Was machst du, wenn malloc0 oder eine neue Ausnahme ausgelöst wird? Einfach anhalten oder versuchen, den OOM-Zustand zu überleben / die Arbeit des Benutzers zu retten?

mbq
quelle
4
Bezogen auf Stackoverflow stackoverflow.com/questions/763159/…
ysolik
11
Argh. Ich lese das immer wieder als "aus Mana". Zu viele Videospiele in meiner Vergangenheit, denke ich. :)
Adam Lear

Antworten:

4

Ich würde die OOM vermeiden, wie einen Absturz zu vermeiden.

Vermeiden Sie es, einen großen Teil der Arbeit gleichzeitig zu erledigen (und einen großen Teil des Speichers zuzuweisen). Behalten Sie die Daten auf der Festplatte, vertrauen Sie dem Festplatten-Cache des Betriebssystems und verwenden Sie so viel wie möglich speicherabgebildete E / A-Vorgänge. Bearbeiten Sie jeweils nur einen kleinen Teil der Daten. Wenn große Datenmengen online sein müssen (mit geringer Latenz), speichern Sie sie auf mehreren Computern im Speicher, wie dies bei allen großen Suchmaschinenunternehmen der Fall ist. Oder kaufen Sie eine SSD.

rwong
quelle
Anscheinend macht das am meisten Sinn.
mbq
2
Es gab eine große Debatte darüber, wie man mit OOM elegant umgeht (RAII, Ausnahmesicherheit, bla ...), aber als ich das in einem Multithread-System mit mehreren dynamischen Modulen (einige von Drittanbietern) erkannte , auch wenn Ihr Thread dies nicht tat Absturz, es gibt einen Moment unglücklicher Zeit, in dem jeder Thread eine OOM sieht. Wenn sich auch nur ein einziger dazu entschlossen hat, können Sie nichts anderes als Augenzeugen tun.
Rwong
13

Die meisten Leute, die diese Frage beantworten, haben wahrscheinlich noch nie an eingebetteten Systemen gearbeitet, bei denen malloc die Rückgabe von 0 eine sehr reale Möglichkeit ist. Auf einem System, an dem ich gerade arbeite, gibt es insgesamt 4,25 KB RAM (das sind 4352 Byte). Ich ordne 64 Bytes für den Stack zu und habe derzeit einen 1600-Byte-Heap. Erst gestern habe ich eine Heap-Walk-Routine getestet, damit ich die Zuweisung und Speicherfreigabe verfolgen kann. Der Heap-Walk verwendet einen kleinen (30 Byte) statisch zugewiesenen Puffer für die Ausgabe an eine serielle Schnittstelle. Es wird für die Release-Version deaktiviert.

Da es sich um ein Verbraucherprodukt handelt, sollte nach der Veröffentlichung des Produkts nicht der Speicher ausgehen. Ich bin mir sicher, dass dies während der Entwicklung der Fall sein wird. In jedem Fall kann ich den Lautsprecher nur ein paar Mal piepen und einen Neustart erzwingen.

tcrosley
quelle
2
Das Anpassen von Funktionen auf kleinem Raum ist erstaunlich ... es ist eine Kunstform wie Bonsai
Rwong
6
Viele Projekte auf eingebetteten Systemen verbieten einfach die dynamische Zuweisung von Speicher. Der einzige Fall von OOM bleibt der Stapelüberlauf.
Mouviciel
Sie haben Recht, aber vor allem mit Ihrem ersten Satz: Das meiste davon ist für die meisten Entwickler zum Glück einfach nicht relevant.
Konrad Rudolph
4

Um ehrlich zu sein, habe ich bei allen Projekten, die ich durchgeführt habe (denken Sie daran, dass ich noch nirgendwo arbeite), nie daran gedacht, dass dies passieren könnte, und daher würde mein Programm wahrscheinlich sehr schnell sterben.

Außerdem müssen Sie für die Bearbeitung eines OOM die Ressourcen vorab zugewiesen haben, um die Fehlermeldung anzuzeigen oder alles zu speichern, was unpraktisch sein kann.

Ich habe das Gefühl, dass heutzutage Speicher, der weniger kostet als Erdnüsse, nicht häufig vorkommen sollte. Zu Beginn des geschützten Gedächtnisses und früher war das vielleicht ein Problem, aber jetzt? Die einzigen OOM-Fehler, die ich jemals gesehen habe, waren fehlerhafter Code.

zneak
quelle
Ich kann mir vorstellen, einen Teil des Speichers, den der Prozess bereits hat, zurückzugewinnen und entweder zu überleben und wiederherzustellen (schwer, wenn Sie etwas Nützliches abgeladen haben) oder als Daten + Überreste zu überleben, die versuchen, ihn zu speichern.
mbq
2

Das Überprüfen der Malloc-Rückkehrcodes ist normalerweise sowieso sinnlos.

Moderne Betriebssysteme überbeanspruchen Speicher: Sie geben Prozessen mehr Speicher als tatsächlich verfügbar ist. Der Speicher, den Ihr Prozess erhält, ist virtuell und alle einer einzelnen Seite mit Nullen zugeordnet.

Erst wenn Sie in den Speicher schreiben, wird Ihren Prozessen eine physische, eindeutige Seite zugewiesen. Wenn diese Zuordnung fehlschlägt, beendet der Kernel einen Prozess (möglicherweise Ihren!), Um Speicher zu finden. Zu diesem Zeitpunkt können Sie nichts mehr tun.

Kristof Provost
quelle
Ich hatte die Idee, in eine while-Schleife mit langem Schlaf zu geraten - und mich möglicherweise zu erholen, wenn der Prozess den OOM-Killer überleben würde. Ich habe den Eindruck, dass die Prozesse aufgrund des Versuchs, die Adresse 0 zu verwenden, eher abgebrochen wurden, aber ich habe keine soliden Tests durchgeführt.
mbq
Sie müssen nichts Besonderes tun, um mit dem OOM-Killer fertig zu werden. Wenn Ihr Prozess es ausgelöst hat, aber nicht ausgewählt wurde, wird es es nie erfahren. Alles wird so funktionieren, als ob es genug Speicher gäbe. Wenn andererseits Ihr Prozess ausgewählt ist, wird er beendet und Sie können auch nichts dagegen tun.
Kristof Provost
Aber ich kann versuchen, darauf zu warten, dass OOM Speicher freigibt, und dann erneut versuchen, zuzuweisen und fortzufahren. Ich habe den Eindruck, dass malloc / new nicht darauf wartet, dass dies geschieht.
mbq
Nein, das kannst du nicht. Ihre Zuordnung wird immer erfolgreich sein. Sie erhalten den gesamten gewünschten virtuellen Speicher. Erst wenn Sie es berühren, wird physischer Speicher zugewiesen. Sobald Sie eine nicht zugewiesene Seite berühren, wird Ihr Prozess angehalten. Der Kernel sucht nach mehr Speicher, was dazu führen kann, dass ein Prozess für mehr Speicher abgebrochen wird. Wenn dies erfolgreich ist (und Ihre nicht tötet!), Wird die Seite zugewiesen und Ihr Prozess wird fortgesetzt. Es gibt keine Möglichkeit für Ihren Prozess zu erkennen, dass dies geschehen ist.
Kristof Provost
2
Ich bin mir ziemlich sicher, dass Windows niemals überlastet. Es kann mehr als das RAM festschreiben, aber nicht mehr als RAM + Swapfile.
CodesInChaos
2

Es sei denn, Sie entwickeln für eingebettete Systeme, Echtzeitsysteme oder Systeme, die so kritisch sind, dass Ausfälle Leben oder Milliarden von Dollar kosten können ... Dann lohnt es sich wahrscheinlich finanziell nicht, sich über Speicherprobleme Gedanken zu machen.

In den meisten Fällen kann ohnehin wenig getan werden, wenn Sie nicht genügend Speicher haben, da kein Speicher vorhanden ist, um neue Objekte zu erstellen oder Aufgaben auszuführen, die möglicherweise etwas bewirken. Sie müssen die Kosten für die App-Handhabung von OOM gegen den Nutzen abwägen, den Sie daraus ziehen.

Erik Funkenbusch
quelle
Echtzeitsysteme müssen nicht mehr über einen Malloc-Fehler prüfen als die anderen Systeme.
Zneak
@zneak - Unwahr. Echtzeitsysteme müssen vorhersehbar sein und nicht genügend Speicher ist vorhersehbar, es sei denn, Sie planen dies speziell.
Erik Funkenbusch
Also, was wirst du noch tun, wenn du die OOM erreicht hast?
Zneak
Freier Speicher, Abbrechen von Prozessen usw. Ein Echtzeitsystem verfügt normalerweise über keinen virtuellen Speicher oder kein Swap-System, da es deterministisch sein muss. Daher kann der Speicher viel leichter ausgehen.
Erik Funkenbusch
Angesichts eines bestimmten Codepfads, der unweigerlich zu einem OOM-Fehler führt, sehe ich keinen weniger deterministischen Ansatz als das Freigeben von Speicher und das Abbrechen von Prozessen.
Zneak
1

Ich würde immer nach Fehlern suchen. Wenn etwas eine Fehlerbedingung zurückgibt, muss dies von Ihrem Programm behandelt werden. Selbst wenn es sich um eine Nachricht handelt, die besagt: "Nicht genügend Speicher, muss gehen!", Ist sie besser als "Zugriffsverletzung", "Core Dumped" oder was auch immer. Eine ist eine Fehlerbedingung, die Sie behandeln, die andere ist ein Fehler. Und der Benutzer wird es auch als solches wahrnehmen.

In Ihrem speziellen Fall können Sie versuchen, den Vorgang zurückzusetzen, die von Ihnen zugewiesenen Ressourcen freizugeben, bis der Fehlerpunkt erreicht ist, den Fehler zu melden und die Ausführung fortzusetzen (möglicherweise können Sie beim Beenden der Anwendung die angeben Option zum sofortigen Beenden). Auf diese Weise kann der Benutzer entscheiden, was zu tun ist, oder versuchen, Speicherplatz freizugeben, indem er herumfummelt, Dateien schließt usw. Natürlich hängt es stark von Ihrem Programm ab, wie Sie mit der Situation umgehen können - ein Programm, das dies nicht tun soll interaktiv sein muss wahrscheinlich nur den Fehler protokollieren und entweder beenden oder fortfahren.

Dysaster
quelle