Wird ein Prozessspeicher wiederhergestellt, wenn er beendet wird?

8

In einer Anwendung von mir ich grundsätzlich Speicher in C++ und Enqueue für die Aufhebung der Zuordnung in C# . Diese Deallokation läuft im Hintergrund und ist nicht deterministisch, also in sehr seltenen Fällen kann es theoretisch passieren, dass die Anwendung beendet wird, bevor der gesamte nicht gemanagte Speicher freigegeben wird.

Wenn das der Fall ist, ist das Verhalten (grob und sehr reduziert) dasselbe wie wenn mein Programm

wäre %Vor%

meine Fragen sind jetzt

  • Ist der gesamte Speicher, den ein Programm zuweist, nicht automatisch freigegeben, wenn das Programm beendet wird oder ist es ein Speicherleck, das bis zum Neustart bleibt?
  • Wenn es automatisch zurückgewonnen wird, welcher Mechanismus ist dafür verantwortlich?

BEARBEITEN: Dies betrifft nur Windows, da einige erwähnten, dass dies vom Betriebssystem abhängig ist.

EDIT 2: Ich spreche nicht über das Ignorieren aller Speicherlecks in meiner Anwendung, sondern darüber, ob ich sicherstellen muss, dass der gesamte Speicher ordnungsgemäß freigegeben wird, bevor die Anwendung beendet wird.

EDIT 3: Es geht nicht um offene Datei-Handles, Destruktoren und Nebeneffekte oder irgendetwas, dies betrifft Speicher, der nicht-determiniert wird, und sehr seltene Fälle, in denen der Speicher vor der Beendigung nicht freigegeben wird.

    
Thomas Flinkow 20.11.2017, 14:48
quelle

5 Antworten

2

Wenn Sie sich nur für den Speicher interessieren, müssen Sie möglicherweise delete nicht aufrufen, da das Betriebssystem Ihren gesamten virtuellen Adressraum zerstört. bei Prozess Beendigung. Lesen Sie Betriebssysteme: Drei einfache Teile (frei herunterladbar), um mehr zu erfahren über Betriebssysteme.

Aber Sie möchten Speicherverlust vermeiden, damit Sie besser sauber machen. Auf manchen Betriebssystemen stehen Tools wie valgrind zur Verfügung, um solche Datenlecks zu erkennen (damit Sie nicht wollen, dass sie falsche Warnungen ausgeben). p>

Lesen Sie auch RAII . Im wirklichen Leben kann der Konstruktor (oder andere Methoden) von Foo (oder von ihm verwendete indirekte Daten) andere Ressourcen (Datenbankverbindungen, geöffnete Dateien, Fenster auf Ihrem Bildschirm, Daemon-Prozesse, Remote-Verbindungen zu externen Diensten oder Webservern) belegen , Roboterarme, etc ...) und Sie möchten, dass sie ordnungsgemäß entsorgt werden.

Erwägen Sie, intelligente Zeiger zu verwenden.

Die Liveness einer Datenstruktur ist eine ganze Programm -Eigenschaft. Ich empfehle, das GC-Handbuch zu lesen, um zumindest die Konzepte und Terminologie von Garbage-Sammlung (die als Möglichkeit zur Verwaltung von Ressourcen und nicht nur von Rohspeicher betrachtet werden kann).

(In der Praxis hängt sehr davon ab : Wenn Sie ein Millionen-Zeilen Code-Programm mit Hunderten anderer Programmierer programmieren, müssen Sie vorsichtiger sein, als wenn Sie programmieren eine winzige Single-Source-Datei-Programm allein, wenn Sie einen Roboter für neuronale Chirurgie codieren ist es nicht das gleiche wie eine Desktop-Anwendung, usw. .... so YMMV)

    
Basile Starynkevitch 20.11.2017, 15:00
quelle
4
  

Ist der gesamte Speicher, den ein Programm zuweist, nicht automatisch freigegeben, wenn das Programm beendet wird oder ist es ein Speicherleck, das bis zum Neustart bleibt?

Der Speicher wird automatisch vom Betriebssystem zurückgewonnen, wenn der Prozess beendet wird.

  

Wenn es automatisch zurückgewonnen wird, welcher Mechanismus ist dafür verantwortlich?

Der Speichermanager von C ++, der hinter new , delete , malloc usw., erhält seinen Speicher in relativ großen Blöcken vom Betriebssystem und ist verantwortlich für die Verwaltung von Speicherstücken mit viel kleinerer Granularität. Das Betriebssystem verfolgt den gesamten Speicher, der einem Prozess zugewiesen wurde, und führt ihn zurück, wenn der Prozess beendet wird.

    
dasblinkenlight 20.11.2017 14:52
quelle
3

Sofern Sie keine Low-Level-Entwicklung betreiben, arbeiten Sie unter einem Betriebssystem. Dieses Betriebssystem verwaltet das reale Memoy, indem es Ihrer Anwendung einen virtuellen Speicher zur Verfügung stellt, der dem realen zugeordnet ist.

Nachdem die Anwendung heruntergefahren wurde (ihr Prozess wurde beendet), entfernt das Betriebssystem die Zuordnung des virtuellen Speichers, wodurch alle Speicherressourcen dieses Prozesses freigegeben werden.

    
Detonar 20.11.2017 14:56
quelle
2

Die Antwort ist, dass Windows den Speicher nach Ihnen bereinigen sollte, wenn dies nicht der Fall ist, sollte es als ein Fehler im Betriebssystem betrachtet werden. Dies gilt auch für Linux und jedes andere System, mit dem Sie einen Prozess vorzeitig beenden können.

Der Grund dafür, und wenn ich es richtig verstehe, ist auch die Situation, die du beschreibst, ist eher wie folgt:

%Vor%

Auch wenn Sie alles so gemacht haben, wie Sie es sollten, und sich selbst ordentlich aufräumen, aufgrund der Option des Betriebssystems, Ihren Prozess vorzeitig zu beenden, führt dies zu einem Speicherleck.

Schließlich, eine wichtige Klarstellung, dies bedeutet nicht, dass Sie das Thema alle zusammen ignorieren können, sollten Sie die beste Anstrengung tun, um nach sich selbst zu reinigen, und zählen Sie nicht auf andere System, um nach Ihnen zu reinigen.

    
OriBS 20.11.2017 15:42
quelle
2

Es gibt zwei verschiedene Ebenen der Speicherzuweisung:

  1. Speicherzuweisung vom Betriebssystem an den Prozess. Dies erfordert einen Syscall (entweder brk() oder mmap() ) und ist vollständig implementiert. Sie sehen das nie selbst.

  2. Speicherzuordnung vom Prozess zu einzelnen Datenobjekten. Das macht operator new() .

new gibt einen Zeiger auf ein Datenobjekt zurück und betrifft somit hauptsächlich die zweite Ebene. % Co_de% selbst hat jedoch keinen Speicher, den es Objekten zuweisen kann, es sei denn, es fragt das Betriebssystem zuerst nach Speicher. Daher muss zuerst eine Zuweisung auf der ersten Ebene durchgeführt werden.

Die Implementierung von new selbst lebt vollständig in Ihrem Prozess. Wenn dein Prozess also auf unnatürliche Weise stirbt (getötet aufgrund eines Signals), erhält die new -Implementierung keine Chance, irgendetwas aufzuräumen. Dies ist jedoch nicht notwendig, da das Betriebssystem selbst den Speicher verfolgt, der auf der ersten Ebene zugewiesen wurde. Es traut einigen zufälligen Prozessen einfach nicht zu, dass sie ihren zugewiesenen Speicher selbst verfolgen. Somit tritt kein permanentes Speicherleck auf.

Das Fehlschlagen von new -Objekten, die mit delete erstellt wurden, hat jedoch Konsequenzen:

  • Ihr Prozess kann den Speicher nicht selbst wiederverwenden. Wenn Sie Objekte, die Sie nicht freigeben können, wiederholt zuweisen, muss Ihre new -Implementierung mehr und mehr Speicherzuweisungen auf der ersten Ebene vornehmen, bis Ihr Betriebssystem keinen Speicher mehr für Ihren Prozess hat.

  • No new bedeutet, dass die jeweiligen Destruktoren nicht aufgerufen wurden. Daher kann Ihr Prozess eine externe Bereinigung verpassen. Wenn Sie beispielsweise ein Objekt nicht löschen, kann dies bedeuten, dass einige temporäre Dateien nicht aus dem Dateisystem entfernt werden, sodass Ihr Prozess Speicherplatz statt Speicher verliert. Und das willst du auch nicht, oder?

cmaster 20.11.2017 15:47
quelle