Wie weit kann Speicherverluste gehen?
Ich habe laufen in den Speicher-Lecks viele Male. In der Regel, wenn ich malloc
-ing als gäbe es kein morgen, oder baumelnd FILE *
s wie schmutzige Wäsche. Ich in der Regel davon ausgehen (lies: hoffe verzweifelt), dass alle Speicher bereinigt wird, zumindest wenn das Programm beendet wird. Gibt es irgendwelche Situationen, in denen die Speicherbelegung wird nicht erhoben, wenn das Programm beendet wird oder abstürzt?
Wenn die Antwort variiert stark von Sprache zu Sprache, dann konzentrieren wir uns auf C(++).
Bitte beachten hyperbolischen Verwendung der phrase "als gäbe es kein morgen', und 'baumeln ... wie schmutzige Wäsche". Unsicher* malloc
*ing weh tun können die, die Sie lieben. Auch, verwenden Sie bitte Vorsicht mit schmutziger Wäsche.
- Wenn Sie mit einem "modernen" OS wie Linux oder Windows, dann das OS selbst wird lösen Sie alle nicht freigegebenen Speicher, wenn das Programm beendet ist.
- Statt malloc-ing als gäbe es kein morgen, versuchen Sie vorgeben, es gibt ein morgen und halten Sie Ihr Gedächtnis!
- ah, Sie sagen also, man sollte
calloc
als gäbe es kein morgen. Ausgezeichnet. - "Wenn die Antwort variiert stark von Sprache zu Sprache, dann läßt sich auf c(++)." c und c++ sind nicht die gleiche Sprache!
- "alle Erinnerung ist aufgeräumt, wenn das Programm beendet" - Durch die Programmierung der Weise, die Sie beschrieben, die Sie ausführen würden, aus dem Speicher schneller, als Sie denken, Sie würden. Beachten Sie, dass Sie nicht immer die Arbeit auf Anwendungen, die ausgeführt wird, nur für ein paar Minuten... Sobald Sie anfangen, die Zusammenarbeit auf einige ernsthafte Projekte, werden Sie erkennen die Bedeutung des korrekten Speicher-management.
- Ich denke, die Frage ist mehr über die
when working in short-lived applications, does memory management matters?
- Mein Punkt ist, dass es in der ordnungsgemäßen Verwaltung und keine Speicherverluste immer, wenn möglich, egal, welche Art von Projekt es ist.
- Kommentar zu C und C++ werden verschiedene Sprachen verbirgt sich mehr, als Sie denken... In C++, Sie werden ziemlich finden sich unter Ausnutzung von Objekten mit automatischer Speicherung-Dauer, - Folgen RAII-idiom... Sie lassen diese Objekte kümmern sich um die Speicherverwaltung für Sie.
- Wenn Sie nicht möchten, um Ihre Speicher von hand, suchen Sie sich ein garbage collector, wie Boehm ' s.
- Was über COM-Objekte? Ich habe gelesen Sie werden nicht freigegeben, wenn Sie vergessen haben, rufen release auf Sie, auch nachdem die Anwendung geschlossen.
- Ich Frage mich, was die Leute von security.stackexchange.com würde sagen, über dieses...
- Es ist nicht genau die Antwort auf deine Frage, aber ich möchte Ihnen in diesem Artikel Wenn Linux Läuft Out-of-Memory Lesen sehr hilfreich...
- Wenn ich das richtig verstehe, ist dies einer der wichtigsten Gründe, warum Windows NT/2000/XP/Vista/8 sind so viel stabiler als Windows 95/98/ME waren: die 95-kernel war nicht in der Lage zu bereinigen nach apps sehr gut (wenn überhaupt?) so ein Programm verrückt und stürzt, könnte leicht bringen das ganze system.
- In C++, es ist besser, verwenden Sie die STL-Containern, wo immer möglich, anstatt neue und löscht. Die STL-Container reinigen sich gut selbst.
- Verwandte Frage: stackoverflow.com/questions/1060160/...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nicht. Betriebssysteme kostenlos alle Ressourcen statt, die durch Prozesse beim beenden.
Dies gilt für alle Ressourcen das Betriebssystem verwaltet: Speicher, offene Dateien, Netzwerkverbindungen, Fenster-Griffe...
Sagte, dass, wenn das Programm läuft auf einem embedded system ohne Betriebssystem oder mit einem sehr einfachen oder fehlerhafte Betriebssystem, der Speicher konnte nicht verwendet werden, bis ein Neustart. Aber wenn du in der situation warst, Sie würde wahrscheinlich nicht diese Frage zu stellen.
Des Betriebssystems dauert eine lange Zeit, sich zu befreien, bestimmte Ressourcen. Zum Beispiel den TCP-port, einen Netzwerk-server verwendet, um verbindungen akzeptieren zu können Minuten nehmen, frei zu sein, auch wenn Sie richtig geschlossen durch das Programm. Eine vernetzte Programm kann auch halten remote Ressourcen wie z.B. Datenbank-Objekte. Das remote-system sollte frei diese Ressourcen, wenn die Netzwerkverbindung verloren gegangen ist, aber es kann auch länger dauern als das lokale Betriebssystem.
ipcrm
für die manuelle Bereinigung, linux.die.net/man/8/ipcrm .C-Standard nicht angeben, dass Speicher
malloc
ist freigegeben, wenn das Programm beendet ist. Dies geschieht, indem das Betriebssystem und die nicht alle Betriebssysteme (normalerweise sind diese in der embedded-Welt) lassen Sie den Speicher, wenn das Programm beendet ist.main
gibt alle Speichermalloc
freigegeben wird. Zum Beispiel heißt es, dass alle geöffneten Dateien geschlossen werden, bevor das Programmende. Für Speicher meinemalloc
, es ist nur nicht angegeben. Jetzt natürlich ist mein Satz bezüglich OS beschreibt, was ist in der Regel nicht, was der Standard vorschreibt, wie Sie nicht angeben, so etwas auf diese.std::atexit
auch der Auffassung, Programm-Beendigung überstd::exit
, und dann gibt ' s auchstd::abort
(C++ spezifisch)std::terminate
.atexit
würde nicht nutzbar sein. 🙂Als alle Antworten abgedeckt haben, die meisten Aspekte Ihrer Frage w.r.t. moderne Betriebssysteme, aber auch historisch, es ist erwähnenswert, wenn Sie jemals programmiert in der DOS-Welt. Terminant and Stay Resident (TSR) Programme würden in der Regel die Steuerung wieder an das system, sondern gespeichert in einem Speicher konnte wiederbelebt werden, durch ein software /hardware-interrupt. Es war normal, zu sehen Nachrichten wie "out of memory! versuchen Sie entladen einige Ihrer Programme" beim arbeiten auf diesen Betriebssystemen.
Technisch So das Programm beendet, sondern weil es befindet sich immer noch auf Speicher, keine Speicher-Lecks würde nicht freigegeben werden, es sei denn, Sie entladen Sie das Programm.
So können Sie der Ansicht, dass dies ein weiterer Fall, abgesehen von den Betriebssystemen nicht reclaiming memory-entweder, weil es buggy ist oder weil der embedded-OS ist entworfen, um zu tun so.
Ich erinnere mich an eine weitere Beispiel. Customer Information Control System (CICS), einer transaction server, das läuft vor allem auf IBM-mainframes, ist pseudo-conversational. Wenn es ausgeführt wird, verarbeitet die vom Benutzer eingegebenen Daten, generiert einen anderen Satz von Daten für den Benutzer, der die übertragung zu dem Benutzer-terminal-Knoten und beendet. Zur Aktivierung der Aufmerksamkeit-Taste, es wieder belebt zu verarbeiten, einen anderen Satz von Daten. Weil die Art, wie er sich verhält, technisch wieder, das OS wird nicht zurückfordern Speicher beendet CICS-Programme, es sei denn, Sie recyceln den CICS transaction server.
Wie die anderen schon sagten, die meisten Betriebssysteme freigeben zugewiesenen Speicher nach der Beendigung des Prozesses (und wahrscheinlich auch andere Ressourcen wie Netzwerk-sockets, file handles, etc).
Gesagt, dass der Speicher möglicherweise nicht die einzige Sache, die Sie brauchen, um über beim Umgang mit new/delete (statt raw malloc/free). Die Speicher, die zugeordnet werden, neue können zurückgefordert erhalten, aber die Dinge, die getan werden in die Destruktoren der Objekte wird nicht passieren. Vielleicht ist der Destruktor einer Klasse schreibt eine sentinel-Wert in eine Datei auf Zerstörung. Wenn der Prozess einfach beendet wird, werden die Datei-handle bekommen kann gespült und der Speicher zurückgefordert, aber das sentinel-Wert nicht geschrieben.
Moral der Geschichte, immer nach sich selbst bereinigen. Lassen Sie sich nicht Dinge, die baumeln. Verlassen Sie sich nicht auf das OS zu bereinigen, nachdem Sie. Bereinigen nach sich selbst.
kill -9
Lüfter zeigt nach oben...)std::exit
rufen dtors,std::abort
nicht, nicht abgefangene Ausnahmen könnten.Dies ist umso wahrscheinlicher, hängt sich das Betriebssystem als Sprache. Letztlich ist jedes Programm in jeder Sprache bekommen, es ist Speicher vom Betriebssystem.
Ich habe noch nie gehört, ein Betriebssystem, das nicht recycle Speicher, wenn ein Programm beendet/stürzt ab. Also, wenn Ihr Programm hat eine Obere Schranke für die Speicher reservieren muss, dann nur reservieren und nie zu befreien, ist durchaus vernünftig.
Wenn das Programm jemals gedreht in eine dynamische Komponente ("plugin"), das geladen wird, in ein anderes Programm-Adressraum, es wird lästig sein, auch auf einem Betriebssystem mit ordentlicher Speicherverwaltung. Wir haben noch nicht einmal zu denken, der code wird portiert auf weniger fähigen Systemen.
Auf der anderen Seite, die Freigabe alle Speicher kann Auswirkungen auf die performance von einem Programm bereinigen.
Einem Programm, an dem ich arbeitete, einen bestimmten Testfall benötigt 30 Sekunden oder mehr für das Programm zu beenden, denn es war recursing durch den Graphen der dynamischen Speicher-und lösen Sie Stück für Stück.
Vernünftige Lösung ist, die Fähigkeit zu haben es und bedecken Sie es mit test-Fällen, aber schalten Sie es aus in der Produktion code, so beendet die Anwendung schnell.
Allen Betriebssystemen verdient den Titel bereinigen, die Unordnung in Ihrem Prozess gemacht, nach der Kündigung. Aber es gibt immer unvorhergesehene Ereignisse, was ist, wenn der Zugriff verweigert wurde und irgendwie ein paar schlechte Programmierer nicht vorhergesehen hat, die Möglichkeit und damit es nicht wieder versuchen, ein bisschen später?
Immer sicherer, einfach zu reinigen sich selbst, WENN memory leaks sind mission critical - sonst nicht wirklich lohnt sich der Aufwand IMO wenn, der Aufwand ist kostspielig.
Bearbeiten:
Sie brauchen, um aufzuräumen Speicher-Lecks, wenn Sie in den Ort, wo Sie sich ansammeln, wie in den Schlingen. Die memory leaks, die ich spreche, sind diejenigen, die aufbauen, in konstanter Zeit während des Kurses das Programm, wenn Sie ein Leck von jeder anderen Art wird es wahrscheinlich ein ernstes problem sein, früher oder später.
In technischer Hinsicht, wenn Ihr Leckagen of memory 'Komplexität' O(1) - Sie sind in Ordnung, in den meisten Fällen, O(logn) schon unangenehm (und in einigen Fällen tödlich) und O(N)+ unerträglich.
Shared memory auf POSIX-konformen Systemen besteht bis shm_unlink aufgerufen wird, oder das system neu gestartet.
Wenn Sie die Kommunikation zwischen Prozessen, kann dies dazu führen, dass andere Prozesse nie abschließen und Ressourcen verbrauchen, je nach Protokoll.
Um ein Beispiel zu geben, war ich mal Experimentieren mit drucken auf einem PDF-Drucker in Java, wenn ich Sie beendet die JVM, in der Mitte ein Drucker, der job, der PDF-spooling-Prozess aktiv blieb, und ich hatte, es zu töten in der task-manager vor, ich könnte wiederholen, drucken.