Warum „verbraucht“ malloc nicht den Speicher auf meinem Computer?
Lesezeit: 4 Minuten
Ich habe also dieses Programm, das 256 MB Speicher zuweist, und nachdem der Benutzer die EINGABETASTE drückt, gibt es den Speicher frei und wird beendet.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char *p, s[2];
p = malloc(256 * 1024 * 1024);
if ( p == NULL)
exit(1);
printf("Allocated");
fgets(s, 2, stdin);
free(p);
return 0;
}
Ich habe dieses Programm mehrmals ausgeführt und jedes Mal im Hintergrund ausgeführt, bis nicht mehr genügend Speicher vorhanden war, der zugewiesen werden konnte. Das passiert jedoch nie. Ich habe ein Linux ausgeführt top Befehl und selbst nach mehrmaliger Ausführung dieses Programms verringert sich der freie Speicher nie um annähernd 256 MB.
Allerdings auf der anderen Seite, wenn ich verwende calloc anstatt malloc dann gibt es einen RIESIGEN Unterschied:
p = calloc(256 * 1024 * 1024, 1);
Wenn ich nun das Programm im Hintergrund ausführe und dies bei jeder Ausführung wiederhole, verringert sich der freie Speicher um 256 MB. Warum ist das? Warum tut malloc nicht dazu führen, dass sich der verfügbare freie Speicher ändert, sondern calloc tut?
Führen Sie das Programm über strace aus und sehen Sie, was es tut. (Ich würde erwarten beide Versionen nach mmap /dev/zero anonym, übrigens)
– wildplasser
15. November 2013 um 1:08
Es heißt „Lazy Allocation“. stackoverflow.com/questions/712683/what-is-lazy-allocation
– jaeheung
15. November 2013 um 1:08
Die kurze, stark vereinfachte Antwort lautet: Da Sie den Speicher von nicht tatsächlich verwendet haben malloc, der Computer muss es Ihnen noch nicht tatsächlich geben. Mit calloc Allerdings muss der Speicher genutzt werden (für den Nullungsteil) und daher muss der Computer Ihnen tatsächlich alles zur Verfügung stellen.
– Dennis Meng
15. November 2013 um 1:09
Der top Und free Die Zahlen zum „freien Speicher“ der Befehle sind bedeutungslos. Bestenfalls informieren sie Sie über die Cache-Effizienz. Die eigentliche aussagekräftige Zahl, Commit-Gebühr, finden Sie in /proc/meminfo als die Committed_AS: Linie.
– R.. GitHub HÖRT AUF, ICE ZU HELFEN
15. November 2013 um 1:25
@DennisMeng: Dies gilt nur für extrem primitiv calloc Implementierungen – aber Ryan verwendet offenbar eine davon. BSD omalloc beispielsweise greift normalerweise nicht auf den Speicher zu.
– mirabilos
31. März 2014 um 20:49 Uhr
chux – Monica wieder einsetzen
malloc() tut nicht Speicher nutzen. Es weist es zu.
Nachdem Sie den Speicher zugewiesen haben, verwenden Sie ihn, indem Sie einige Daten zuweisen.
size_t Size = 256 * 1024 * 1024;
p = malloc(Size);
if (p != NULL) {
memset(p, 123, Size);
}
Einige Plattformen implementieren malloc() ist so, dass der physische Speicherverbrauch erst auftritt, wenn auf dieses Byte (oder wahrscheinlicher auf ein Byte innerhalb einer Gruppe oder „Seite“ von Bytes) zugegriffen wird.
calloc() kann wirklich sein oder auch nicht verwenden auch die Erinnerung. Ein System könnte Karte viel Speicher auf den gleichen physikalisch auf Null gesetzten Speicher, zumindest bis die Daten interessant werden. Siehe Warum ist malloc+memset langsamer als calloc?
Ist 123 Ihre Glückszahl? 256 MB von 123 123 123 123… Muss großes Glück sein!
– Fummelei-Teile
20. Dezember 2013 um 20:40 Uhr
sicherlich sollte es 42 sein
– 100 Uhr
12. November 2018 um 18:21 Uhr
Der Speicher ist möglicherweise nicht wirklich verfügbar, insbesondere wenn Sie ihn nicht genutzt haben p in Ihrem Beispiel, außer prüfen Sie, ob dies der Fall ist NULL. Aus Mann malloc
Standardmäßig folgt Linux einer optimistischen Speicherzuweisungsstrategie. Das bedeutet, wann malloc() gibt nicht zurückNULL Es gibt keine Garantie dafür, dass der Speicher tatsächlich verfügbar ist. Falls sich herausstellt, dass das System nicht über genügend Arbeitsspeicher verfügt, werden ein oder mehrere Prozesse durch den OOM-Killer getötet. Weitere Informationen finden Sie in der Beschreibung von /proc/sys/vm/overcommit_memory Und /proc/sys/vm/oom_adj In proc(5)und die Linux-Kernel-Quelldatei-Dokumentation /vm/overcommit-accounting.
Arkku
Der calloc auf Ihrem System† tatsächlich den Speicher berührt, indem es ihn löscht, und auf vielen Systemen wird Speicher erst dann wirklich zugewiesen (und daher „verbraucht“), wenn er von dem Prozess berührt wird, dem er zugewiesen ist. Also einfach machen malloc „benutzt“ den Speicher erst, wenn Sie ihn nutzen.
† Zeige Kommentare
Ich finde calloc() kann auf einigen Systemen auch betrügen stackoverflow.com/questions/2688466/…
– chux – Monica wieder einsetzen
15. November 2013 um 1:18
@chux Interessant, das wusste ich nicht, danke für den Link. (Mittlerweile hat der Fragesteller gefunden calloc Und malloc unterscheiden sich in ihrem System und ihren Parametern.)
– Arkku
15. November 2013 um 1:22
Einverstanden. Es ist nicht bekannt und trifft im Fall von OP sicherlich nicht zu. Diese hinterhältigen OS-Gremlins!
– chux – Monica wieder einsetzen
15. November 2013 um 1:27
14528200cookie-checkWarum „verbraucht“ malloc nicht den Speicher auf meinem Computer?yes
Führen Sie das Programm über strace aus und sehen Sie, was es tut. (Ich würde erwarten beide Versionen nach mmap /dev/zero anonym, übrigens)
– wildplasser
15. November 2013 um 1:08
Es heißt „Lazy Allocation“. stackoverflow.com/questions/712683/what-is-lazy-allocation
– jaeheung
15. November 2013 um 1:08
Die kurze, stark vereinfachte Antwort lautet: Da Sie den Speicher von nicht tatsächlich verwendet haben
malloc
, der Computer muss es Ihnen noch nicht tatsächlich geben. Mitcalloc
Allerdings muss der Speicher genutzt werden (für den Nullungsteil) und daher muss der Computer Ihnen tatsächlich alles zur Verfügung stellen.– Dennis Meng
15. November 2013 um 1:09
Der
top
Undfree
Die Zahlen zum „freien Speicher“ der Befehle sind bedeutungslos. Bestenfalls informieren sie Sie über die Cache-Effizienz. Die eigentliche aussagekräftige Zahl, Commit-Gebühr, finden Sie in/proc/meminfo
als dieCommitted_AS:
Linie.– R.. GitHub HÖRT AUF, ICE ZU HELFEN
15. November 2013 um 1:25
@DennisMeng: Dies gilt nur für extrem primitiv
calloc
Implementierungen – aber Ryan verwendet offenbar eine davon. BSD omalloc beispielsweise greift normalerweise nicht auf den Speicher zu.– mirabilos
31. März 2014 um 20:49 Uhr