Ist es jemals in Ordnung, free () für den zugewiesenen Speicher * nicht * zu verwenden?

83

Ich studiere Computertechnik und habe einige Elektronikkurse. Ich habe gehört, von zwei meiner Professoren (diese Kurse) , dass es möglich ist , das zu vermeiden , mit free()Funktion (nach malloc(), calloc()usw.) , da die Speicherplatz wahrscheinlich zugewiesen wird nicht wieder verwendet werden , um andere Speicher zuweisen. Das heißt, wenn Sie beispielsweise 4 Bytes zuweisen und diese dann freigeben, haben Sie 4 Bytes Speicherplatz, der wahrscheinlich nicht erneut zugewiesen wird: Sie haben ein Loch .

Ich finde das verrückt: Sie können kein Nicht-Spielzeug-Programm haben, in dem Sie Speicher auf dem Heap zuweisen, ohne ihn freizugeben. Aber ich habe nicht das Wissen, um genau zu erklären, warum es so wichtig ist, dass es für jeden einen malloc()geben muss free().

Also: Gibt es jemals Umstände, unter denen es angebracht sein könnte, a malloc()ohne zu verwenden free()? Und wenn nicht, wie kann ich das meinen Professoren erklären?

Nick
quelle
11
Sie sind nicht "falsch" - sie haben einen gültigen (wenn auch begrenzten) Punkt bezüglich der Fragmentierung sehr kleiner isolierter freier Regionen und haben ihn wahrscheinlich etwas sorgfältiger angegeben, als Sie es gemeldet haben.
Chris Stratton
2
Sie müssen nur dann keinen Speicher freigeben, wenn Sie verwalteten Speicher verwenden oder den ursprünglich zugewiesenen Speicher wiederverwenden. Ich vermute, dass der Grund, warum zwei Instruktoren dies gesagt haben, darin besteht, dass Sie über ein bestimmtes Programm sprechen, das den Speicher wiederverwenden kann. In diesem Fall würden Sie weiterhin free () verwenden, jedoch nur am Ende Ihrer Anwendung. Bist du sicher, dass dies nicht ihre Bedeutung war?
Krowe
17
@Marian: Ich hatte eine Behauptung eines Professors, dass es in C und C ++ notwendig ist, Ihren zugewiesenen Speicher in einer Funktion freizugeben, die in derselben .c / .cxx-Datei definiert ist, in der er zugewiesen wurde ... Diese Personen scheinen manchmal stark an Hypoxie zu leiden weil ich zu hoch in einem Elfenbeinturm lebe.
PlasmaHH
4
Es gibt eine ganze Reihe von Nicht-Spielzeug-Programmen, die keinen Speicher freigeben, und es ist viel schneller, wenn das Betriebssystem beim Beenden des Prozesses alles bereinigt, als (umständlich) viel Buch zu führen, damit Sie es selbst tun können.
Donal Fellows
9
Führen Sie niemals unbestrittene Inhalte in Ihr Gehirn ein. Ich hatte viele Lehrer, Lektoren und Korrektoren, die falsch oder veraltet waren. Und analysieren Sie immer sehr genau, was sie sagen. Unser Volk ist oft sehr präzise und sagt vielleicht etwas, das richtig ist, aber von jemandem, der sich nur im allgemeinen Sprachgebrauch zu Hause fühlt, leicht falsch oder mit der falschen Priorität zu verstehen ist. Ich erinnere mich beispielsweise, dass ein Lehrer in der Schule sagte: "Hast du deine Hausaufgaben gemacht?", Ich sagte: "Nein." Während ich Recht hatte, fand der Lehrer diese Beleidigung, weil ich mir die Zeit ersparte, lahme Ausreden zu finden, die er nicht erwartet hatte.
Sebastian Mach

Antworten:

100

Einfach: Lesen Sie einfach die Quelle so ziemlich jeder halb-ernsthaften malloc()/free()Implementierung. Damit meine ich den eigentlichen Speichermanager , der die Arbeit der Anrufe erledigt. Dies kann sich in der Laufzeitbibliothek, der virtuellen Maschine oder dem Betriebssystem befinden. Natürlich ist der Code nicht in allen Fällen gleichermaßen zugänglich.

Es ist sehr üblich, sicherzustellen, dass der Speicher nicht fragmentiert wird, indem benachbarte Löcher zu größeren Löchern zusammengefügt werden. Seriösere Allokatoren verwenden seriösere Techniken, um dies sicherzustellen.

Nehmen wir also an, Sie führen drei Zuweisungen und Aufhebungen durch und erhalten Blöcke, die in dieser Reihenfolge im Speicher angeordnet sind:

+-+-+-+
|A|B|C|
+-+-+-+

Die Größe der einzelnen Zuordnungen spielt keine Rolle. dann befreien Sie den ersten und den letzten, A und C:

+-+-+-+
| |B| |
+-+-+-+

Wenn Sie B endgültig befreien, erhalten Sie (zunächst zumindest theoretisch) Folgendes:

+-+-+-+
| | | |
+-+-+-+

was in gerecht zerlegt werden kann

+-+-+-+
|     |
+-+-+-+

dh ein einzelner größerer freier Block, keine Fragmente mehr übrig.

Referenzen, wie gewünscht:

  • Versuchen Sie, den Code für dlmalloc zu lesen . Ich bin viel weiter fortgeschritten und habe eine vollständige Implementierung in Produktionsqualität.
  • Selbst in eingebetteten Anwendungen sind De-Fragmentierungs-Implementierungen verfügbar. Siehe zum Beispiel diese Hinweise zum heap4.cCode in FreeRTOS .
entspannen
quelle
1
Können Sie mir einige Referenzen geben?
Nick
4
Ich denke, es wäre erwähnenswert, dass der virtuelle Adressraum keine direkte Darstellung des physischen Speichers ist. Und diese Fragmentierung im physischen Speicher kann vom Betriebssystem behoben werden, während der virtuelle Prozess, der nicht vom Prozess freigegeben wird, auch nicht physisch freigegeben wird.
Lapk
@PetrBudnik es wäre selten, dass der virtuelle Speicher 1-1 auf den physischen Speicher abbildet, das Betriebssystem wird in Seitenzuordnungen denken und in der Lage sein, es mit minimalem Aufwand ein- und auszutauschen
Ratschenfreak
3
Sehr pingeliger Kommentar: Während das Konzept gut erklärt ist, wurde das eigentliche Beispiel ein bisschen ausgewählt .. unglücklich. Für alle, die sich den Quellcode von say dlmalloc ansehen und verwirrt sind: Blöcke unter einer bestimmten Größe sind immer Potenzen von 2 und werden entsprechend zusammengeführt / aufgeteilt. Wir würden also (möglicherweise) einen 8-Byte-Block und einen 4-Byte-Block haben, aber keinen 12-Byte-Block. Dies ist ein ziemlich normaler Ansatz für Allokatoren, zumindest auf Desktops, obwohl eingebettete Anwendungen möglicherweise versuchen, mit ihrem Overhead vorsichtiger umzugehen.
Voo
@Voo Ich habe die Erwähnung einer Größe für die Blöcke im Beispiel entfernt, es war sowieso egal. Besser?
Entspannen Sie am
42

Die anderen Antworten erklären , bereits sehr gut , dass reale Implementierungen malloc()und free()tun in der Tat coalesce (defragmnent) Löcher in größeren freien Stücken. Aber selbst wenn dies nicht der Fall wäre, wäre es immer noch eine schlechte Idee, darauf zu verzichten free().

Die Sache ist, dass Ihr Programm gerade diese 4 Bytes Speicher zugewiesen hat (und freigeben möchte). Wenn es über einen längeren Zeitraum ausgeführt wird, ist es sehr wahrscheinlich, dass erneut nur 4 Byte Speicher zugewiesen werden müssen. Selbst wenn diese 4 Bytes niemals zu einem größeren zusammenhängenden Raum verschmelzen, können sie dennoch vom Programm selbst wiederverwendet werden.

Angew ist nicht mehr stolz auf SO
quelle
6
+1 Genau. Die Sache ist, wenn freees oft genug aufgerufen wird, um die Leistung zu beeinträchtigen, dann wird es wahrscheinlich auch oft genug aufgerufen, so dass das Auslassen eine sehr große Beeinträchtigung des verfügbaren Speichers zur Folge hat. Es ist schwer vorstellbar, dass auf einem eingebetteten System die Leistung ständig darunter leidet, freeaber mallocnur eine endliche Anzahl von Malen genannt wird. Es ist ein ziemlich seltener Anwendungsfall, ein eingebettetes Gerät zu haben, das Daten einmalig verarbeitet und dann zurücksetzt.
Jason C
10

Es ist totaler Unsinn, zum Beispiel gibt es viele verschiedene Implementierungen von malloc, einige versuchen, den Haufen effizienter zu machen, wie Doug Leas oder dieser .

Paul Evans
quelle
9

Arbeiten Ihre Professoren zufällig mit POSIX? Wenn sie es gewohnt sind, viele kleine, minimalistische Shell-Anwendungen zu schreiben, ist dies ein Szenario, in dem ich mir vorstellen kann, dass dieser Ansatz nicht allzu schlecht wäre - das Freigeben des gesamten Heaps auf einmal in der Freizeit des Betriebssystems ist schneller als das Freigeben von a tausend Variablen. Wenn Sie erwarten, dass Ihre Anwendung ein oder zwei Sekunden lang ausgeführt wird, können Sie problemlos ohne Aufhebung der Zuordnung davonkommen.

Es ist natürlich immer noch eine schlechte Praxis (Leistungsverbesserungen sollten immer auf Profilerstellung basieren, nicht auf vagen Bauchgefühlen), und Sie sollten den Schülern nichts sagen, ohne die anderen Einschränkungen zu erklären, aber ich kann mir eine Menge winziger Rohrleitungen vorstellen -Anwendungen, die auf diese Weise geschrieben werden sollen (wenn die statische Zuordnung nicht direkt verwendet wird). Wenn Sie an etwas arbeiten, das davon profitiert, dass Ihre Variablen nicht freigegeben werden, arbeiten Sie entweder unter extrem niedrigen Latenzbedingungen (in diesem Fall, wie können Sie sich überhaupt dynamische Zuweisung und C ++ leisten ?: D), oder Sie sind es etwas sehr, sehr Falsches tun (wie das Zuweisen eines Ganzzahl-Arrays durch Zuweisen von tausend Ganzzahlen nacheinander anstelle eines einzelnen Speicherblocks).

Luaan
quelle
Wenn Sie das Betriebssystem am Ende freigeben, geht es nicht nur um Leistung, sondern auch um viel weniger Logik, um arbeiten zu können.
Hugomg
@missingno Mit anderen Worten, Sie können damit durchkommen, wie schwierig die Speicherverwaltung sein kann :) Ich würde dies jedoch als Argument gegen nicht verwaltete Sprachen ansehen - wenn Ihr Grund eher eine komplizierte Freigabelogik als eine Leistung ist, sind Sie möglicherweise besser Verwenden Sie eine Sprache / Umgebung, die sich für Sie darum kümmert.
Luaan
5

Sie haben erwähnt, dass sie Elektronikprofessoren sind. Sie können zum Schreiben von Firmware / Echtzeitsoftware verwendet werden, wenn sie in der Lage sind, die Ausführung einer bestimmten Zeit genau zu bestimmen. In diesen Fällen kann es einfacher sein, die Ausführungszeit zu berechnen, wenn Sie wissen, dass Sie über genügend Speicher für alle Zuweisungen verfügen und nicht Speicher freigeben und neu zuweisen.

In einigen Schemata kann der Hardwarespeicherschutz auch verwendet werden, um sicherzustellen, dass die Routine in ihrem zugewiesenen Speicher abgeschlossen ist, oder um in sehr außergewöhnlichen Fällen eine Falle zu erzeugen .

Paddy3118
quelle
10
Das ist ein guter Punkt. Ich würde jedoch erwarten, dass sie mallocund solche in diesem Fall überhaupt nicht verwenden würden , anstatt sich auf die statische Zuordnung zu verlassen (oder vielleicht einen großen Teil zuzuweisen und dann den Speicher manuell zu handhaben).
Luaan
2

Aus einem anderen Blickwinkel als bei früheren Kommentatoren und Antworten besteht die Möglichkeit, dass Ihre Professoren Erfahrung mit Systemen haben, bei denen der Speicher statisch zugewiesen wurde (dh als das Programm kompiliert wurde).

Die statische Zuordnung erfolgt, wenn Sie Folgendes tun:

define MAX_SIZE 32
int array[MAX_SIZE];

In vielen Echtzeit- und eingebetteten Systemen (die am wahrscheinlichsten von EEs oder CEs angetroffen werden) ist es normalerweise vorzuziehen, die dynamische Speicherzuweisung insgesamt zu vermeiden. Also, Verwendungen von malloc,new und ihre Gegenstücke zum Löschen selten. Darüber hinaus ist der Speicher in Computern in den letzten Jahren explodiert.

Wenn Ihnen 512 MB zur Verfügung stehen und Sie statisch 1 MB zuweisen, müssen Sie ungefähr 511 MB durchlaufen, bevor Ihre Software explodiert (na ja, nicht genau ... aber gehen Sie hier mit mir). Angenommen, Sie haben 511 MB zu missbrauchen. Wenn Sie 4 Bytes pro Sekunde mallocieren, ohne sie freizugeben, können Sie fast 73 Stunden lang laufen, bevor Ihnen der Speicher ausgeht. Wenn man bedenkt, dass viele Computer einmal am Tag ausgeschaltet werden, bedeutet dies, dass Ihrem Programm niemals der Speicher ausgeht!

Im obigen Beispiel beträgt das Leck 4 Bytes pro Sekunde oder 240 Bytes / min. Stellen Sie sich nun vor, Sie senken das Byte / Min-Verhältnis. Je niedriger dieses Verhältnis, desto länger kann Ihr Programm problemlos ausgeführt werden. Wenn Ihre mallocs selten sind, ist das eine echte Möglichkeit.

Wenn Sie wissen, dass Sie nur malloceinmal zu etwas gehen und das mallocnie wieder getroffen wird, ähnelt dies einer statischen Zuordnung, obwohl Sie nicht wissen müssen, wie groß das ist, was Sie zuweisen. Vorderseite. Beispiel: Nehmen wir an, wir haben wieder 512 MB. Wir müssenmalloc 32 Arrays von ganzen Zahlen. Dies sind typische Ganzzahlen - jeweils 4 Bytes. Wir wissen, dass die Größe dieser Arrays niemals 1024 Ganzzahlen überschreiten wird. In unserem Programm treten keine weiteren Speicherzuordnungen auf. Haben wir genug Speicher? 32 * 1024 * 4 = 131.072. 128 KB - also ja. Wir haben viel Platz. Wenn wir wissen, dass wir niemals mehr Speicher zuweisen werden, können wir dies sicher tunmallocdiese Arrays, ohne sie zu befreien. Dies kann jedoch auch bedeuten, dass Sie den Computer neu starten müssen, wenn Ihr Programm abstürzt. Wenn Sie Ihr Programm 4.096 Mal starten / stoppen, weisen Sie alle 512 MB zu. Wenn Sie Zombie-Prozesse haben, ist es möglich, dass Speicher auch nach einem Absturz nie freigegeben wird.

Sparen Sie sich Schmerz und Elend und konsumieren Sie dieses Mantra als Die Eine Wahrheit: mallocsollte immer mit einem assoziiert werden free. newsollte immer eine haben delete.

Shaz
quelle
2
In den meisten eingebetteten Systemen und Echtzeitsystemen wäre eine Zeitbombe, die bereits nach 73 Stunden ausfällt, ein ernstes Problem.
Ben Voigt
typische ganze Zahlen ??? Die Ganzzahl ist mindestens eine 16-Bit-Zahl und bei kleinen Mikrochips normalerweise eine 16-Bit-Zahl. Im Allgemeinen gibt es mehr Geräte mit sizeof(int)gleich 2 statt 4.
ST3
2

Ich denke, die in der Frage angegebene Behauptung ist Unsinn, wenn sie vom Standpunkt des Programmierers aus wörtlich genommen wird, aber sie hat aus Sicht des Betriebssystems die Wahrheit (zumindest einige).

malloc () ruft schließlich entweder mmap () oder sbrk () auf, wodurch eine Seite vom Betriebssystem abgerufen wird.

In jedem nicht trivialen Programm ist die Wahrscheinlichkeit, dass diese Seite während einer Prozesslebensdauer jemals an das Betriebssystem zurückgegeben wird, sehr gering, selbst wenn Sie den größten Teil des zugewiesenen Speichers freigeben (). Der freie Speicher von () würde also die meiste Zeit nur für denselben Prozess verfügbar sein, nicht jedoch für andere.

mfro
quelle
2

Ihre Professoren sind nicht falsch, aber auch falsch (sie sind zumindest irreführend oder zu stark vereinfacht). Die Speicherfragmentierung führt zu Problemen bei der Leistung und der effizienten Nutzung des Speichers. Manchmal müssen Sie dies berücksichtigen und Maßnahmen ergreifen, um dies zu vermeiden. Ein klassischer Trick besteht darin, dass Sie, wenn Sie viele Dinge mit derselben Größe zuweisen, beim Start einen Speicherpool abrufen, der ein Vielfaches dieser Größe beträgt, und dessen Verwendung vollständig intern verwalten, um sicherzustellen, dass beim Fragmentieren keine Fragmentierung auftritt Betriebssystemebene (und die Löcher in Ihrem internen Speicher-Mapper haben genau die richtige Größe für das nächste Objekt dieses Typs).

Es gibt ganze Bibliotheken von Drittanbietern, die nichts anderes tun, als solche Dinge für Sie zu erledigen, und manchmal ist es der Unterschied zwischen akzeptabler Leistung und etwas, das viel zu langsam läuft. malloc()und free()nehmen Sie sich merklich Zeit für die Ausführung, was Sie bemerken werden, wenn Sie sie häufig anrufen.

Also nur um naiv zu vermeiden verwenden malloc()und free()Sie können sowohl die Fragmentierung und Leistungsprobleme vermeiden - aber wenn Sie rechts unten , um es zu bekommen, sollten Sie immer sicherstellen , dass Sie free()alles , was Sie , malloc()wenn Sie einen sehr guten Grund, es anders zu machen. Selbst wenn ein interner Speicherpool verwendet wird, wird der Poolspeicher von einer guten Anwendung free()vor dem Beenden verwendet. Ja, das Betriebssystem wird es bereinigen, aber wenn der Anwendungslebenszyklus später geändert wird, kann man leicht vergessen, dass der Pool immer noch herumhängt ...

Langzeitanwendungen müssen natürlich äußerst gewissenhaft sein, wenn es darum geht, alles, was sie zugewiesen haben, zu bereinigen oder zu recyceln, da ihnen sonst der Speicherplatz ausgeht.

Matthew Walton
quelle
1

Ihre Professoren sprechen einen wichtigen Punkt an. Leider ist der englische Sprachgebrauch so, dass ich nicht ganz sicher bin, was sie gesagt haben. Lassen Sie mich die Frage in Bezug auf Nicht-Spielzeug-Programme beantworten, die bestimmte Eigenschaften der Speichernutzung aufweisen und mit denen ich persönlich gearbeitet habe.

Einige Programme verhalten sich gut. Sie ordnen Speicher in Wellen zu: viele kleine oder mittlere Zuordnungen, gefolgt von vielen Freigaben, in sich wiederholenden Zyklen. In diesen Programmen sind typische Speicherzuordnungen ziemlich gut. Sie verschmelzen freigegebene Blöcke und am Ende einer Welle befindet sich der größte Teil des freien Speichers in großen zusammenhängenden Blöcken. Diese Programme sind ziemlich selten.

Die meisten Programme verhalten sich schlecht. Sie weisen den Speicher mehr oder weniger zufällig in einer Vielzahl von Größen von sehr klein bis sehr groß zu und geben ihn frei, und sie behalten eine hohe Verwendung der zugewiesenen Blöcke bei. In diesen Programmen ist die Fähigkeit zum Zusammenführen von Blöcken begrenzt und im Laufe der Zeit endet der Speicher stark fragmentiert und relativ nicht zusammenhängend. Wenn die Gesamtspeicherauslastung in einem 32-Bit-Speicherbereich etwa 1,5 GB überschreitet und Zuweisungen von (z. B.) 10 MB oder mehr vorhanden sind, schlägt möglicherweise eine der großen Zuweisungen fehl. Diese Programme sind üblich.

Andere Programme geben wenig oder gar keinen Speicher frei, bis sie aufhören. Sie weisen während der Ausführung nach und nach Speicher zu, geben nur kleine Mengen frei und stoppen dann. Zu diesem Zeitpunkt wird der gesamte Speicher freigegeben. Ein Compiler ist so. So ist eine VM. Beispielsweise gibt die in C ++ selbst geschriebene .NET CLR-Laufzeit wahrscheinlich nie Speicher frei. Warum sollte es?

Und das ist die endgültige Antwort. In den Fällen, in denen das Programm über ausreichend Speicher verfügt, ist die Verwaltung des Speichers mit malloc und free keine ausreichende Antwort auf das Problem. Sofern Sie nicht das Glück haben, mit einem gut erzogenen Programm zu arbeiten, müssen Sie einen oder mehrere benutzerdefinierte Speicherzuweiser entwerfen, die große Speicherblöcke vorab zuweisen und dann gemäß einer Strategie Ihrer Wahl unterzuweisen. Sie dürfen free überhaupt nicht verwenden, außer wenn das Programm stoppt.

Ohne genau zu wissen, was Ihre Professoren gesagt haben, würde ich für Programme im Produktionsmaßstab wahrscheinlich auf ihrer Seite stehen.

BEARBEITEN

Ich werde versuchen, einige der Kritikpunkte zu beantworten. Offensichtlich ist SO kein guter Ort für Beiträge dieser Art. Um es klar zu sagen: Ich habe ungefähr 30 Jahre Erfahrung im Schreiben dieser Art von Software, einschließlich einiger Compiler. Ich habe keine akademischen Referenzen, nur meine eigenen blauen Flecken. Ich kann nicht anders, als zu spüren, dass die Kritik von Menschen mit weitaus engeren und kürzeren Erfahrungen kommt.

Ich werde meine Kernbotschaft wiederholen: Das Ausbalancieren von Malloc und Free ist keine ausreichende Lösung für die Speicherzuweisung in großem Maßstab in realen Programmen. Block Coalescing ist normal und kostet Zeit, reicht aber nicht aus. Sie benötigen seriöse, clevere Speicherzuordnungen, die dazu neigen, Speicher in Blöcken (mit Malloc oder was auch immer) zu erfassen und selten freizugeben. Dies ist wahrscheinlich die Botschaft, die die Professoren von OP im Sinn hatten und die er missverstanden hat.

david.pfx
quelle
1
Die Programme mit schlechtem Verhalten zeigen, dass anständige Allokatoren separate Pools für Blöcke unterschiedlicher Größe verwenden sollten. Mit virtuellem Speicher sollte es kein großes Problem sein, viele verschiedene Pools weit voneinander entfernt zu haben. Wenn jeder Block auf eine Zweierpotenz aufgerundet wird und jeder Pool somit gerundete Blöcke von nur einer Größe enthält, kann ich nicht sehen, wie die Fragmentierung jemals sehr schlimm werden könnte. Im schlimmsten Fall könnte ein Programm plötzlich aufhören, sich für einen bestimmten Größenbereich zu interessieren, so dass einige weitgehend leere Pools ungenutzt bleiben. Ich denke jedoch nicht, dass dies ein sehr häufiges Verhalten ist.
Marc van Leeuwen
5
Zitieren sehr wichtig für die Behauptung, dass kompetent geschriebene Programme erst nach dem Schließen der App Speicher freigeben.
12
Diese gesamte Antwort liest sich wie eine Reihe zufälliger Vermutungen und Vermutungen. Gibt es irgendetwas, um dies zu belegen?
Chris Hayes
4
Ich bin mir nicht sicher, was Sie damit meinen, dass die .NET CLR-Laufzeit keinen Speicher frei macht. Soweit ich es getestet habe, wenn es geht.
Theodoros Chatzigiannakis
1
@vonbrand: GCC verfügt über mehrere Allokatoren, einschließlich einer eigenen Marke von Garbage Collector. Es verbraucht während der Durchläufe Speicher und sammelt ihn zwischen den Durchläufen. Die meisten Compiler für andere Sprachen haben höchstens 2 Durchgänge und zwischen den Durchläufen wenig oder keinen Speicherplatz frei. Wenn Sie nicht einverstanden sind, recherchiere ich gerne nach einem Beispiel, das Sie geben.
david.pfx
1

Ich bin überrascht, dass noch niemand das Buch zitiert hat:

Dies ist möglicherweise nicht der Fall, da die Speicher möglicherweise groß genug werden, sodass während der Lebensdauer des Computers kein freier Speicherplatz mehr zur Verfügung steht. Zum Beispiel gibt es ungefähr 3 × 10 13 Mikrosekunden pro Jahr. Wenn wir also einmal pro Mikrosekunde Nachteile hätten, würden wir ungefähr 10 benötigen 15 Zellen Speicher , um eine Maschine zu bauen, die 30 Jahre lang arbeiten könnte, ohne dass der Speicher knapp wird. So viel Gedächtnis scheint nach heutigen Maßstäben absurd groß zu sein, aber es ist physikalisch nicht unmöglich. Auf der anderen Seite werden Prozessoren immer schneller und ein zukünftiger Computer verfügt möglicherweise über eine große Anzahl von Prozessoren, die parallel auf einem einzelnen Speicher arbeiten. Daher kann der Speicher möglicherweise viel schneller verbraucht werden, als wir postuliert haben.

http://sarabander.github.io/sicp/html/5_002e3.xhtml#FOOT298

In der Tat können viele Programme problemlos funktionieren, ohne sich jemals die Mühe zu machen, Speicherplatz freizugeben.

Oakad
quelle
1

Ich kenne einen Fall, in dem das explizite Freigeben von Speicher schlimmer als nutzlos ist . Das heißt, wenn Sie alle Ihre Daten bis zum Ende der Prozesslebensdauer benötigen . Mit anderen Worten, wenn sie freigegeben werden, ist dies nur unmittelbar vor Beendigung des Programms möglich. Da jedes moderne Betriebssystem darauf achtet, Speicherplatz freizugeben, wenn ein Programm stirbt, ist ein Aufruf free()in diesem Fall nicht erforderlich. Tatsächlich kann dies die Programmbeendigung verlangsamen, da möglicherweise auf mehrere Seiten im Speicher zugegriffen werden muss.

Miklós Homolya
quelle