Ist der Heap-Speicher pro Prozess? (oder) Gemeinsamer Speicherort für verschiedene Prozesse?

8

Jeder Prozess kann Heap-Speicher verwenden, um Daten innerhalb des Prozesses zu speichern und zu teilen. Wir haben eine Regel in der Programmierung, wann immer wir etwas Platz im Heapspeicher nehmen, wir müssen es freigeben, sobald der Job erledigt ist, sonst führt es zu Speicherlecks.

%Vor%

Meine Frage: Ist der Heapspeicher pro Prozess?

Wenn JA,

  

dann Speicherverlust ist nur möglich, wenn ein Prozess im laufenden Zustand ist.

Wenn NEIN,

  

bedeutet, dass das Betriebssystem Daten in einem Speicher speichern kann. Wenn ja, gibt es eine Möglichkeit, auf diesen Speicher durch einen anderen Prozess zuzugreifen. Dies kann auch ein Weg für die Kommunikation zwischen den Prozessen werden.

Ich nehme an, Antwort auf meine Frage ist JA. Bitte geben Sie Ihr wertvolles Feedback an.

    
AKN 30.06.2010, 06:54
quelle

6 Antworten

15

Auf fast jedem derzeit verwendeten System ist der Heap-Speicher pro Prozess. Auf älteren Systemen ohne geschützten Speicher war der Heap-Speicher systemweit. (Kurz gesagt, das ist der geschützte Speicher : Er macht Ihren Heap und Stack privat für Ihren Prozess.)

Wenn in Ihrem Beispielcode auf einem modernen System der Prozess beendet wird, bevor delete pIntPtr aufgerufen wird, wird pIntPtr immer noch freigegeben (obwohl sein Destruktor, nicht dass ein int einen hat, nicht aufgerufen würde.)

Beachten Sie, dass geschützter Speicher ein Implementierungsdetail ist, nicht ein Feature der C ++ - oder C-Standards. Ein System ist frei, Speicher zwischen Prozessen zu teilen (moderne Systeme nur nicht , weil es eine gute Möglichkeit ist, Ihren Hintern von einem Angreifer zu erhalten.)

    
Jonathan Grynspan 30.06.2010, 06:59
quelle
3

In den meisten modernen Betriebssystemen hat jeder Prozess seinen eigenen Heap, auf den nur dieser Prozess zugreifen kann und der nach Beendigung des Prozesses zurückgewonnen wird - dieser "private" Heap wird normalerweise von new verwendet. Außerdem könnte es einen globalen Heap geben (schauen Sie sich Win32 GlobalAlloc() Familie an) Funktionen zum Beispiel), die von Prozessen gemeinsam genutzt werden, für die Systemlaufzeit bestehen bleiben und tatsächlich für die Interprozesskommunikation verwendet werden können.

    
sharptooth 30.06.2010 06:56
quelle
1

Im Allgemeinen erfolgt die Zuweisung von Speicher zu einem Prozess auf einer niedrigeren Ebene als die Heapverwaltung.

Mit anderen Worten, der Heap wird innerhalb des virtuellen Prozessadressraums erstellt, der dem Prozess vom Betriebssystem zugewiesen wird, und ist für diesen Prozess privat. Wenn der Prozess beendet wird, wird dieser Speicher vom Betriebssystem zurückgewonnen.

Beachten Sie, dass C ++ dies nicht vorschreibt. Dies ist Teil der Ausführungsumgebung, in der C ++ ausgeführt wird, so dass die ISO-Standards dieses Verhalten nicht vorschreiben. Was ich diskutiere ist eine gemeinsame Implementierung.

In UNIX wurden die Systemaufrufe brk und sbrk verwendet, um mehr Arbeitsspeicher vom Betriebssystem zu reservieren, um den Heap zu erweitern. Sobald der Prozess abgeschlossen war, wurde der gesamte Speicher an das Betriebssystem zurückgegeben.

Der normale Weg, um Speicher zu erhalten, der einen Prozess überleben kann, ist Shared Memory (unter UNIX-Betriebssystemen, nicht sicher über Windows). Diese kann zu einem Leck, aber mehr zu Systemressourcen als zu Prozessressourcen führen.

    
paxdiablo 30.06.2010 06:59
quelle
1

Es gibt einige spezielle Betriebssysteme, die Speicher beim Beenden des Prozesses nicht zurückfordern. Wenn Sie auf ein solches Betriebssystem abzielen, wissen Sie das wahrscheinlich.

Die meisten Systeme erlauben Ihnen nicht, auf den Speicher eines anderen Prozesses zuzugreifen, aber wieder ... es gibt einige einzigartige Situationen, in denen dies nicht der Fall ist.

Der C ++ - Standard behandelt diese Situation, indem er keinen Anspruch darauf erhebt, was passiert, wenn Sie Speicher nicht freigeben und dann beenden, und was passiert, wenn Sie versuchen, auf Speicher zuzugreifen, auf den Sie nicht explizit zugreifen können. Dies ist das Wesentliche dessen, was "undefiniertes Verhalten" bedeutet und der Kern dessen ist, was es bedeutet, dass ein Zeiger "ungültig" ist. Es gibt mehr Probleme als nur diese beiden, aber diese beiden spielen eine Rolle.

    
Crazy Eddie 30.06.2010 07:13
quelle
0

Normalerweise wird das O / S jeden ausgelaufenen Speicher zurückfordern, wenn der Prozess beendet wird.

Aus diesem Grund denke ich, dass es für C ++ - Programmierer in Ordnung ist, niemals Speicher freizugeben, der benötigt wird, bis der Prozess beendet wird; Zum Beispiel werden alle 'Singletons' innerhalb eines Prozesses oft nicht explizit freigegeben.

Dieses Verhalten kann jedoch O / S-spezifisch sein (obwohl es sowohl für Windows als auch für Linux gilt): nicht theoretisch Teil des C ++ - Standards.

    
ChrisW 30.06.2010 07:00
quelle
0

Aus praktischen Gründen lautet die Antwort auf Ihre Frage ja. Moderne Betriebssysteme geben im Allgemeinen Speicher frei, der von einem Prozess zugewiesen wird, wenn dieser Prozess heruntergefahren wird. Sich von diesem Verhalten abhängig zu machen, ist jedoch eine sehr schäbige Übung. Selbst wenn wir sicher sein können, dass Betriebssysteme immer so funktionieren, ist der Code fragil. Wenn eine Funktion, die den Speicher nicht freigibt, plötzlich für einen anderen Zweck wiederverwendet wird, kann dies zu einem Speicherleck auf Anwendungsebene führen.

Nichtsdestoweniger erfordert die Natur dieser Frage und des angeführten Beispiels ethisch, dass ich Sie und Ihr Team auf RAII aufmerksam mache.

%Vor%

Dieser Code riecht nach Speicherlecks. Wenn etwas in [...] wirft, haben Sie ein Speicherleck. Es gibt mehrere Lösungen:

%Vor%

Zweite Lösung, die nothrow verwendet (nicht unbedingt viel besser als zuerst, aber ermöglicht eine sinnvolle Initialisierung von pIntPtr zu dem Zeitpunkt, zu dem es definiert ist):

%Vor%

Und der einfache Weg:

%Vor%

In diesem letzten und besten Beispiel ist es nicht notwendig, delete auf pIntPtr aufzurufen, da dies automatisch geschieht, unabhängig davon, wie wir diesen Block verlassen (Hurray für RAII und Smart Pointer).

    
stinky472 30.06.2010 07:36
quelle