Reserviert malloc mehr Speicherplatz beim Zuweisen von Speicher?

Lesezeit: 6 Minuten

Benutzer-Avatar
Benutzer1228352

Ich beobachte in meinem Testprogramm folgendes Verhalten:

ich mache malloc() für 1 MB und dann free() es nach sleep(10). Ich mache das fünfmal. Ich beobachte den Speicherverbrauch in top während das Programm läuft.

Einmal free()-d, erwarte ich, dass der Verbrauch des virtuellen Speichers (VIRT) des Programms um 1 MB gesunken ist. Aber eigentlich ist es das nicht. Es bleibt stabil. Was ist die Erklärung für dieses Verhalten? Tut malloc() Reservieren Sie etwas, während Sie Speicher zuweisen?

  • Verwandte: Wie gebe ich Speicher in C frei?

    – Ludin

    22. März 2019 um 13:51 Uhr

  • Ein mögliches Duplikat der Speichernutzung nimmt nicht ab, wenn free() verwendet wird

    – Nicht zu gebrauchen

    22. März 2019 um 16:29 Uhr

  • @Useless Diese Frage hat bessere Antworten als die ältere, also habe ich mich gegen die Konvention gewehrt und die alte Frage als Duplikat dieser Frage markiert.

    – John Kugelmann

    22. März 2019 um 18:32 Uhr

  • Ich denke, fast alle malloc/free-Implementierungen verwenden ein internes Management, das größere Chunks anfordert und sie opportunistisch freigibt. Dies kann verwenden brk(2) oder mmap. Es bedeutet auch, dass Seiten möglicherweise nicht wirklich verwendet werden, bevor sie berührt werden (und manchmal sogar kostenlos freigegeben werden, sodass die virtuelle oder Datensegmentgröße nicht so wichtig ist).

    – eckes

    22. März 2019 um 19:42 Uhr

Benutzer-Avatar
Sourav Ghosh

Einmal free()-d, ich erwarte, dass der Verbrauch des virtuellen Speichers (VIRT) des Programms um 1 MB gesunken ist.

Nun, dies wird durch den C-Standard nicht garantiert. Es sagt nur, einmal du free() den Speicher, sollten Sie nicht mehr darauf zugreifen.

Ob der Speicherblock tatsächlich an den verfügbaren Speicherpool zurückgegeben oder für zukünftige Zuweisungen reserviert wird, entscheidet der Speichermanager.

  • Ist es möglich, den free()-Speicherblock wieder für das Betriebssystem freizugeben?

    – Benutzer1228352

    22. März 2019 um 7:59 Uhr

  • @ user1228352 nein, die C-Sprache erlaubt dies nicht. Wenn Sie mehr Kontrolle wünschen, müssen Sie Ihren eigenen Speichermanager implementieren, der auf plattformspezifischen Betriebssystemaufrufen basiert.

    – Jabberwocky

    22. März 2019 um 8:30 Uhr

  • @ user1228352 Ich verstehe das Gefühl danach, sagen wir Trickserei, aber – Sie wollen diesen Weg wirklich nicht gehen, und es macht auch keinen Sinn im langfristigen Ansatz, weil es nur Zeitverschwendung für Sie ist, herauszufinden, wie es geht Erstellen Sie Ihren eigenen Speichermanager (falls vom Betriebssystem zugelassen) und debuggen Sie ihn. Gehen Sie nach dem C-Standard und Sie werden ein angenehmeres Erlebnis haben, während das Betriebssystem das tut, wofür es gemacht wurde. Nun, es sei denn, Ihr Ziel ist es, Ihr eigenes Betriebssystem zu erstellen, aber dann würden Sie diese Frage wahrscheinlich nicht stellen.

    – Peter Badida

    22. März 2019 um 14:15 Uhr

  • @ user1228352 Warum solltest du das wollen? Virtueller Speicher ist praktisch kostenlos.

    – David Schwartz

    22. März 2019 um 23:27 Uhr

  • Warum sollten Sie den unnötigen Verbrauch von etwas reduzieren, das nicht knapp ist? Sie sollten uns viel mehr über Ihre Umgebung erzählen, wenn Sie eine hilfreiche Antwort wünschen. Einige ungewöhnliche Umgebungen haben auch ungewöhnliche Implementierungen von malloc und free. Wenn Sie ein echtes Problem haben (und das ist nicht nur kosmetisch), können Sie den Allocator durch einen ersetzen, der niemals zusätzlichen virtuellen Speicher enthält, aber es besteht eine Wahrscheinlichkeit von etwa 99%, dass dies aufgrund von Problemen wie Fragmentierung nur noch schlimmer wird.

    – David Schwartz

    23. März 2019 um 18:41 Uhr

Benutzer-Avatar
Amin

Der C-Standard zwingt den Implementierer nicht dazu malloc und free um den Speicher direkt an das Betriebssystem zurückzugeben. Daher verhalten sich verschiedene C-Bibliotheksimplementierungen unterschiedlich. Einige von ihnen geben es möglicherweise direkt zurück und andere möglicherweise nicht. Tatsächlich verhält sich dieselbe Implementierung abhängig von den Zuordnungsgrößen und -mustern auch unterschiedlich.

Dieses Verhalten hat natürlich gute Gründe:

  1. Es ist nicht immer möglich. Speicherzuweisungen auf Betriebssystemebene erfolgen normalerweise in Seiten (Größen von 4 KB, 4 MB oder … auf einmal). Und wenn ein kleiner Teil der Seite noch verwendet wird, nachdem ein anderer Teil freigegeben wurde, kann die Seite nicht an das Betriebssystem zurückgegeben werden, bis auch dieser Teil freigegeben ist.
  2. Effizienz. Es ist sehr wahrscheinlich, dass eine Anwendung erneut Speicher anfordert. Warum es also dem Betriebssystem zurückgeben und kurz darauf erneut danach fragen? (Natürlich gibt es wahrscheinlich eine Grenze für die Größe des beibehaltenen Speichers.)

In den meisten Fällen sind Sie für die Erinnerung nicht verantwortlich free wenn die Implementierung entschieden hat, es beizubehalten (vorausgesetzt, es ist eine gute Implementierung). Früher oder später wird es neu zugewiesen oder an das Betriebssystem zurückgegeben. Daher sollte die Optimierung der Speichernutzung auf der Menge basieren, die Sie haben malloc-ed und du hast es nicht free-d. Der Fall, in dem Sie sich darüber Sorgen machen müssen, ist, wenn Ihre Zuordnungsmuster / -größen anfangen, eine Speicherfragmentierung zu verursachen, was für sich genommen ein sehr großes Thema ist.

Wenn Sie sich jedoch auf einem eingebetteten System befinden und die verfügbare Speichermenge begrenzt ist und Sie mehr Kontrolle darüber benötigen, wann/wie Speicher zugewiesen und freigegeben wird, müssen Sie Speicherseiten direkt vom Betriebssystem anfordern und manuell verwalten.

Bearbeiten: Ich habe nicht erklärt, warum Sie nicht für den von Ihnen freien Speicher verantwortlich sind. Der Grund dafür ist, dass auf einem modernen Betriebssystem der zugewiesene Speicher virtuell ist. Das heißt, wenn Sie 512 MB auf einem 32-Bit-System oder 10 TB auf einem 64-Bit-System zuweisen, wird kein physischer Speicherplatz dafür reserviert, solange Sie nicht in diesen Speicher lesen oder schreiben. Tatsächlich wird nur physischer Speicher für die Seiten reserviert, die Sie von diesem großen Block aus berühren, und nicht für den gesamten Block. Und nach “einer Weile, in der dieser Speicher nicht verwendet wird”, wird sein Inhalt auf die Festplatte kopiert und der zugrunde liegende physische Speicher wird für etwas anderes verwendet.

  • Beachten Sie, dass einige Zuordner möglicherweise die Möglichkeit vermeiden, Daten auf die Festplatte zu kopieren, indem sie betriebssystemspezifische Aufrufe verwenden, die besagen: “Diese Seiten werden nicht verwendet, also können Sie ihren Inhalt löschen, auch wenn ich den virtuellen Speicher selbst nicht freigebe”. Beispiel wäre die Verwendung von madvise unter Linux mit aufrufen MADV_DONTNEED.

    – ShadowRanger

    23. März 2019 um 5:14 Uhr

Dies hängt stark von der tatsächlich verwendeten Malloc-Implementierung ab.

Unter Linux gibt es einen Schwellenwert (MMAP_THRESHOLD) zu entscheiden, wo der Speicher für eine gegeben ist malloc() Anfrage kommt von.

Wenn der angeforderte Betrag kleiner oder gleich ist MMAP_THRESHOLDwird die Anforderung erfüllt, indem sie entweder aus der sogenannten “freien Liste” genommen wird, falls bereits Speicherblöcke vorhanden sind free()d. Ansonsten der “Bruchlinie” des Programms (also das Ende des Datensegments) erhöht und der durch diesen Prozess dem Programm zur Verfügung gestellte Speicher für die Anforderung verwendet.

An free(), wird der freigegebene Speicherblock zur freien Liste hinzugefügt. Wenn ganz am Ende des Datensegments genügend freier Speicher vorhanden ist, wird die Unterbrechungslinie (oben erwähnt) erneut verschoben, um das Datensegment zu verkleinern und den überschüssigen Speicher an das Betriebssystem zurückzugeben.

Wenn der angeforderte Betrag überschritten wird MMAP_THRESHOLDwird ein separater Speicherblock vom Betriebssystem angefordert und währenddessen wieder zurückgegeben free().

Siehe auch https://linux.die.net/man/3/malloc für Details.

1381520cookie-checkReserviert malloc mehr Speicherplatz beim Zuweisen von Speicher?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy