2016-04-09 16 views
-2

Ich wurde gelehrt, dass, wenn Sie malloc() tun, aber Sie nicht frei(), der Speicher bleibt, bis ein Neustart geschieht. Nun, ich habe es natürlich getestet. Ein sehr einfacher Code:C malloc und frei

#include <stdlib.h> 

int main(void) 
{ 
    while (1) malloc(1000); 
} 

Und ich wachte über sie in Task Manager (Windows 8.1).

Nun, das Programm nahm 2037.4   MB wirklich schnell auf und blieb einfach so. Ich verstehe, dass Windows wahrscheinlich das Programm einschränkt.

Aber hier ist der komische Teil: Als ich die Konsole schloss, ging der Speicherverbrauch prozentual zurück, obwohl mir beigebracht wurde, dass es nicht soll!

Ist es redundant, frei zu rufen, da das Betriebssystem es sowieso freigibt?

(Die Frage über here ist verwandt, aber nicht antwortet ganz, ob ich frei soll oder nicht.)

+3

Denken Sie an ein Programm, das eine lange Zeit - wie Ihr Browser - läuft und das viele Threads verwendet. Wenn jeder Thread ein Speicherleck von einem Megabyte pro Webseite (Beispiel) verursacht, stellen Sie sich vor, was nach einem Tag passiert. Sie sollten 'free' verwenden. Es ist eine gute Übung. – blazs

+2

Wenn der Speicher durch den Lebenszyklus des Prozesses lebt, dann würde OS das für Sie tun. aber sehr selten sollte die Erinnerung die volle Lebensdauer eines Prozesses leben. – user3528438

+2

http://stackoverflow.com/q/2215259/1606345 –

Antwort

5

Unter Windows kann ein 32-Bit-Prozess nur 2048 Megabyte zuweisen, da so viele Adressen vorhanden sind. Ein Teil dieses Speichers wird wahrscheinlich von Windows umgekehrt, daher ist die Gesamtanzahl niedriger. malloc gibt einen Nullzeiger zurück, wenn es fehlschlägt, was wahrscheinlich an diesem Punkt passiert. Sie könnten Ihr Programm wie folgt ändern, um zu sehen, dass:

#include <stdlib.h> 
#include <stdio.h> 

int main(void) 
{ 
    int counter = 0; 
    while (1) { 
     counter++; 
     if (malloc(1000) == NULL) { 
      printf("malloc failed after %d calls\n", counter); 
      return 0; 
     } 
    } 
} 

Jetzt sollten Sie eine Ausgabe wie diese:

$ ./mem 
malloc failed after 3921373 calls 

Wenn ein Prozess beendet wird, oder wenn es von außen beendet (wie Sie von tun Durch den Task-Manager wird der gesamte vom Prozess zugewiesene Speicher freigegeben. Das Betriebssystem verwaltet, welcher Speicher zu welchem ​​Prozess gehört und kann daher den Speicher eines Prozesses freigeben, wenn er beendet wird. Das Betriebssystem weiß jedoch nicht, wie jeder Prozess den vom Betriebssystem angeforderten Speicher verwendet, und hängt davon ab, ob der Prozess es angibt, wenn kein Speicher mehr benötigt wird.

Warum brauchen Sie dann free()? Nun, das passiert nur beim Beenden des Programms und unterscheidet nicht zwischen Speicher, den Sie noch benötigen und Speicher, den Sie nicht mehr brauchen. Wenn Ihr Prozess komplizierte Dinge erledigt, wird häufig Speicher für seine eigenen Berechnungen zugewiesen und freigegeben. Es ist wichtig, Speicher explizit mit free() freizugeben, da Ihr Prozess sonst möglicherweise nicht mehr in der Lage ist, neuen Speicher und Abstürze zuzuweisen. Es ist auch eine gute Programmierpraxis, Speicher freizugeben, wenn Sie können, damit Ihr Prozess nicht unnötig viel Speicher verbraucht. Stattdessen können andere Prozesse diesen Speicher verwenden.

4

Es ist ratsam, free zu nennen, nachdem Sie mit dem Speicher durchgeführt werden Sie zugeteilt worden, so können Sie benötigen Sie diesen Speicherplatz später in Ihrem Programm und es wird ein Problem, wenn es keinen Speicherplatz für neue Zuordnungen gab. Sie sollten Portabilität für Ihren Code immer suchen. Wenn Windows diesen Speicherplatz freigibt, können andere Betriebssysteme dies nicht tun.

1

Jeder Prozess im Betriebssystem hat eine begrenzte Menge an adressierbarem Speicher, der als Prozessadressraum bezeichnet wird. Wenn Sie eine große Menge an Arbeitsspeicher zuweisen und Sie den gesamten für diesen Prozess verfügbaren Arbeitsspeicher zuweisen, schlägt Malloc fehl und gibt NULL zurück. Und Sie können nicht mehr Speicher für diesen Prozess reservieren.

+0

Sie haben den Punkt der Frage verpasst. Ich weiß, dass Betriebssysteme den Speicher von Prozessen begrenzen, ich habe nach der automatischen Bereinigung gefragt. –

+0

@AmitGold Nein, Sie wissen nicht, dass OS Prozessspeicher begrenzt, sonst hätten Sie diese Frage nicht gestellt. Und deine Frage ist ein Duplikat und in zwei Sekunden bei Google auffindbar. (http://stackoverflow.com/questions/2215259/will-malloc-implementations-return-free-ed-memory-back-to-the-system) –

0

Bei allen nicht-trivialen Betriebssystemen werden Prozessressourcen nach Abschluss des Prozesses vom Betriebssystem zurückgewonnen.

Es sei denn, es ist specifc und zwingenden Grund ausdrücklich freien Speicher bei Beendigung Sie es nicht tun müssen, und Sie sollten mindestens diese Gründe nicht versuchen:

1) Sie würden Code schreiben müssen Mach es und teste es und debugge es. Warum, wenn das OS es kann? Es ist nicht nur redundant, es reduziert auch die Qualität, da Ihr explicit resource-releasing niemals so viel Test bekommt, wie es das Betriebssystem bereits hatte, bevor es veröffentlicht wurde.

2) mit einem komplexen App, mit einer grafischen Benutzeroberfläche und viele Subsysteme und Threads, sauber Speicher beim Herunterfahren zu befreien ist nahezu unmöglich sowieso, was zu:

3) Viel Bibliothek Entwickler bereits bis auf gegeben haben Das Mantra muss man explizit loslassen, weil die Komplexität dazu führen würde, dass die Bibliotheken niemals freigegeben würden. Viele berichten von unveröffentlichtem (aber nicht verlorenem) Speicher für Valgrid, und mit undurchsichtigen Bibliotheken können Sie überhaupt nichts dagegen tun.

4) Sie dürfen keinen Speicher freigeben, der von einem laufenden Thread verwendet wird. Um den gesamten Speicher in Multithread-Anwendungen sicher freigeben zu können, müssen Sie sicherstellen, dass alle Prozessthreads gestoppt sind und nicht erneut ausgeführt werden können. Der Benutzercode verfügt nicht über die entsprechenden Tools, das Betriebssystem. Es ist daher nicht möglich, Speicher von Benutzercode in solchen Apps auf sichere Weise explizit freizugeben.

5) Das Betriebssystem kann den Prozessspeicher in großen Blöcken freigeben - viel schneller als mit Dutzenden von Sub-Allkationen im C-Manager.

6) Wenn der Prozess beendet wird, weil er aufgrund von Speicherverwaltungsproblemen fehlgeschlagen ist, wird der Aufruf von free() viel öfter nicht helfen.

7) Viele Lehrer und Professoren sagen, dass Sie explizit die Erinnerung frei haben müssen, also ist es offensichtlich ein schlechter Plan.