UNIX- und Windows-Speicherfreigabe

7

Mein Verständnis ist, dass in Unix, wenn Speicher freigegeben wird, der Speicher nicht zurück zum Betriebssystem zurückgegeben wird, bleibt es in dem Prozess für den nächsten Aufruf von malloc erneut verwendet werden.

Unter Windows verstehe ich, dass der Speicher tatsächlich an das Betriebssystem zurückgegeben wird.

Gibt es einen großen Unterschied zwischen diesen beiden Arten, Dinge zu tun, oder sind es nur zwei verschiedene Arten, dasselbe zu tun? Und wenn es für diese beiden Methoden irgendwelche Vorteile / Nachteile gibt, was sind sie?

BEARBEITEN: Danke für die Klarstellung. Ich hatte immer gedacht, dass dies eine Sache mit dem Betriebssystem war (da Prozesse in UNIX-ähnlichen Systemen nie kleiner zu werden scheinen, aber in Windows).

    
Jason Baker 25.10.2008, 06:25
quelle

9 Antworten

14

Es gibt keinen großen Unterschied zwischen Windows und Unix.

In beiden gibt es zwei Zuordnungsebenen. Das Betriebssystem weist dem Prozess Speicher in großen Abschnitten zu (eine Seite oder mehr; auf x86 beträgt die Seitengröße normalerweise 4096 Byte). Die Laufzeitbibliotheken, die innerhalb des Prozesses ausgeführt werden, unterteilen diesen Speicherplatz und weisen Teile davon Ihrem Code zu.

Um den Speicher an das Betriebssystem zurückzugeben, muss zuerst der gesamte von einem dieser großen Blöcke zugewiesene Speicher für die Laufzeitbibliothek freigegeben werden. Die Laufzeitbibliothek kann dann, wenn sie es wünscht, dem Betriebssystem mitteilen, diesen Speicherbereich freizugeben.

Unter Linux haben Sie brk und mmap . brk steuert die Größe eines großen Speicherblocks, der Ihrem Prozess zugewiesen ist. Sie können es erweitern oder verkleinern, aber nur an einem Ende. malloc erweitert dieses Speichersegment traditionell, wenn mehr Speicher benötigt wird, um es zuzuordnen, und verkleinert es, wenn dies möglich ist. Schrumpfen ist jedoch nicht einfach; Es braucht eine einzige unzeitgemäße Ein-Byte-Zuweisung am Ende, um es unmöglich zu machen, selbst dann zu schrumpfen, wenn alles vor dieser Zuweisung freigegeben wurde. Dies ist die Quelle der "Unix gibt keinen Speicher zurück" Mem.

Allerdings gibt es auch anonym mmap . Anonymous mmap fordert einen Teil des Speichers vom Betriebssystem an, der an einer beliebigen Stelle im Prozessspeicherplatz platziert werden kann. Dieser Chunk kann leicht zurückgegeben werden, wenn er nicht mehr benötigt wird, selbst wenn später Zuteilungen vorhanden sind, die noch nicht freigegeben wurden. malloc verwendet auch mmap (besonders für große Zuordnungen, bei denen ein ganzes Stück Speicher nach dem Freigeben leicht zurückgegeben werden kann).

Natürlich können Sie sowohl unter Windows als auch unter Linux, wenn Sie das Verhalten der Speicherzuordner (oder Zuordner) aus den Laufzeitbibliotheken nicht mögen, Ihre eigenen verwenden, Speicher vom Betriebssystem abfragen und ihn nach Ihren Wünschen aufteilen (oder manchmal Speicher von einem anderen Zuordner, aber in größeren Blöcken). Eine interessante Verwendung besteht darin, einen Zuordner für den gesamten Speicher zu haben, der mit einer Aufgabe verknüpft ist (z. B. eine Webserveranfrage), die am Ende der Aufgabe vollständig verworfen wird (ohne dass alle Teile einzeln freigegeben werden müssen); Eine weitere interessante Anwendung ist ein Zuordner für Objekte fester Größe (z. B. Objekte mit fünf Byte), wodurch eine Speicherfragmentierung vermieden wird.

    
CesarB 25.10.2008, 12:40
quelle
6

Beachten Sie, dass ich im Folgenden viel mehr über Windows als Unix weiß ...

Was tatsächlich mit der Speicherzuweisung und -freigabe passiert, ist auf jeden Fall nicht das, was Sie beschreiben. Das liegt daran, dass hier zwei sehr unterschiedliche Konzepte im Spiel sind: der physische Speicher, den der Computer besitzt, und der virtuelle Adressraum des Programms, der Speicher, den Ihr Programm zu nutzen glaubt.

Wenn Ihr Programm mehr Speicher vom Betriebssystem anfordert, geschieht tatsächlich, dass der zuvor nicht verfügbare virtuelle Adressraum in Ihrem Programm als vom Programm zugänglich eingerichtet wird. Moderne Betriebssysteme funktionieren nicht, indem sie nur einen Pool von "echtem" (dh physikalischem) Speicher haben, den sie an Prozesse ausgibt, wenn sie eine Zuweisungsanforderung stellen: Sie verwaltet den virtuellen Adressraum für jedes laufende Programm und wann Programme greifen tatsächlich auf Teile dieses virtuellen Adressraums zu, stellen sicher, dass dies einem physikalischen Speicher zugeordnet wird, möglicherweise durch Austauschen eines Teils des Adressraums eines anderen Programms mit der Auslagerungsdatei auf dem Datenträger.

Als Beispiel wird unter Windows jeder Thread mit (standardmäßig) einem Megabyte Stack-Speicherplatz gestartet, der dafür reserviert ist. Dies bedeutet nicht, dass jeder Thread ein Megabyte des physischen Speichers der Maschine verbraucht: Es ist einfach so, dass der Adressraum so eingerichtet ist, dass er für die Verwendung verfügbar ist. In diesem Sinne funktioniert es nicht wirklich, über das Betriebssystem nachzudenken, das Ihren Programmspeicher gibt und dann das Programm, das es zurückgibt - es funktioniert einfach nicht so.

    
DavidK 25.10.2008 07:22
quelle
4

Es hängt alles davon ab, welche C-Laufzeitbibliothek Sie verwenden. Es gibt KEINE spezielle UNIX-Art oder WINDOWS-Art. Jeder Compiler-Hersteller (HP, SUN, MS, GNU) wird mit einer eigenen Laufzeitbibliothek ausgeliefert, die die Logik für malloc enthält. Jede Implementierung von malloc wird je nach Betriebssystem gleich / verschieden funktionieren. Weder UNIX / LINUX / Windows benötigt eine freie "AKTUELLE RÜCKGABE" des Speichers an das OS. Das wäre zu teuer (da Ihre alloc () in sehr kleinen Stücken wäre)

Kürzlich hat Mozilla Firefox eine malloc () Implementierung von * BSD OS ausgeliehen. Sie entschieden sich dafür, ein anderes malloc zu verwenden, als das, was ihr Compiler-Anbieter (mehrfach in diesem Fall - gcc und VC ++) geliefert hat. Da sie ein bestimmtes Verhalten wollten, bekamen sie, was sie wollten.

    
anjanb 25.10.2008 07:30
quelle
2

Von diesem Memory Management Artikel

  

Malloc gibt den freigegebenen Speicher normalerweise nicht an das Betriebssystem zurück; es bleibt bis zum Beenden des Prozesses im Besitz des Prozesses. Der Prozess kann ihn bei der nächsten Anforderung von mehr Speicher erneut verwenden, aber andere Programme haben keinen Zugriff darauf, auch wenn kein anderer Speicher verfügbar ist. Folglich ist der Speicherbedarf eines Programms die Größe der größten Zuordnungen, die zu einem bestimmten Zeitpunkt vorgenommen werden. Daher ist es immer ratsam, Objekte, die Sie nicht benötigen, besonders große, so schnell wie möglich zu entfernen, um diesen Fußabdruck zu minimieren.

Dieser Artikel schlägt vor, dass in Windows, zumindest für C-Programm, der Speicher nicht an das Betriebssystem zurückgegeben wird.

Ich bin mir also nicht sicher über Ihre Verallgemeinerung der Freigabe von Windows-Speicher.

Das heißt, Sie können UNIX-Speicherverwaltung unter Microsoft Windows emulieren , indem Sie low level implementieren System ruft sbrk und mmap / munmap unter Windows auf.

    
VonC 25.10.2008 06:32
quelle
2

Das einzige Betriebssystem, bei dem Sie nicht einfach reservierten Speicher dem System zurückgeben können, ist OS X - Zitat Firefox 3 Speicherverbrauch :

  

Nach ausgiebigen Tests und   Bestätigung von Apple Mitarbeitern wir   erkannte, dass es keinen Weg für einen gab   Allokator, um ungenutzte Seiten von   Erinnerung zurück, während die Adresse beibehalten wird   Bereich reserviert .. (Sie können sie aufheben   und neu zuordnen, aber das verursacht einige   Rennbedingungen und ist nicht so   performant). Es gibt APIs, die behaupten   (madvise () und msync ())   aber sie machen eigentlich gar nichts.

    
Hugh Allen 25.10.2008 08:01
quelle
2

Wie bereits erwähnt, ist dies eher mit der malloc-Implementierung als mit dem Betriebssystem selbst verbunden. Auf Linux, mit glibc, wird der Speicher tatsächlich immer oberhalb einer bestimmten Größe an das Betriebssystem zurückgegeben: glibc malloc verwendet mmap für große Zuweisungen (gesteuert von MMAP_THRESHOLD), und in diesem Fall gibt es kostenlose Aufrufe munmap, die automatisch den reservierten Speicher freigeben. Unterhalb dieses Schwellenwerts wird brk verwendet, und free gibt den Speicher in diesem Fall nicht zurück.

Beachten Sie, dass die obige Erklärung nicht exakt ist: Um genau zu sein, müssen Sie den Unterschied zwischen physikalischem Speicher, virtuellem Speicher usw. kennen. Dies wird hier gut erklärt:

Ссылка

    
David Cournapeau 25.10.2008 08:37
quelle
1

Ich weiß nichts über Windows, aber unter UNIX wird der Aufruf brk() verwendet, um mehr Speicher in den Adressraum zu bringen, um von den malloc() -Aufrufen verwendet zu werden.

Ich habe noch nie gesehen, dass dieser Speicher zum Betriebssystem zurückgekehrt ist, bis der Prozess beendet ist. Sie können dies normalerweise mit Tools wie top sehen.

Ich vermute, dass das Verhalten für Windows das gleiche wäre, aber ich weiß, dass Windows andere Zuordnungsfunktionen als malloc() hat, die dies tun können (Teil der Win32-API).

    
paxdiablo 25.10.2008 06:37
quelle
1

Andere Poster haben den plattformspezifischen Blickwinkel kommentiert. Aber da Sie speziell nach malloc fragen, sehen Sie, was der C-Standard sagt:

"Die freie Funktion bewirkt, dass der Raum, auf den ptr verweist, freigegeben wird, also gemacht wird verfügbar für die weitere Zuweisung. "

Das scheint eine ziemlich klare Anforderung zu sein, dass der Speicher nicht an das Betriebssystem zurückgegeben wird. Sie sehen gelegentlich Programme, die auf diesem Verhalten beruhen:

%Vor%

Wenn diese Frage jedoch auf comp.lang.c gestellt wurde, haben einige Poster auf diesen Abschnitt hingewiesen:

"Die malloc-Funktion gibt entweder einen Nullzeiger oder einen Zeiger auf den zugewiesenen Speicherplatz zurück."

Dies deutet darauf hin, dass jeder Aufruf von malloc fehlschlagen kann. Es scheint, dass die Absicht des Standards darin besteht, dass Speicher nicht an das Betriebssystem zurückgegeben wird, aber das Problem ist in den Augen von Sprachanwälten nicht zu 100% sicher.

    
fizzer 25.10.2008 08:38
quelle
0

Die malloc-Funktion gibt entweder einen Nullzeiger oder einen Zeiger auf den zugewiesenen Speicherplatz zurück. "

Dies deutet darauf hin, dass jeder Aufruf von malloc fehlschlagen kann. Es scheint, dass die Absicht des Standards ist, dass Speicher nicht an das Betriebssystem zurückgegeben wird.

    
Kipyego 18.03.2015 07:21
quelle