Gut, der Arbeitsspeicher wird nicht linear, sondern mehr chaotisch vergeben, aber im Prinzip sollte es so klar werden
Code:
. while True do
begin
1 a := nil; // ja, das geht auch ^^
2 SetLength(a, i);
i := i * 2;
end;
mit zurücksetzen ohne zurücksetzen
2 |* |*
1 | |*
2 |++ |*++
1 | | ++
2 |**** | ++****
1 | | ****
2 |++++++++ | ****++++++++
1 | | ++++++++
2 |**************** | ++++++++****************
= |################ |---------------################
Wenn Delphi das Array vergrößer/verkleiner muß und das nicht inplace geht, indem hinten dran neuer Speicher angehängt oder entfernt wird, dann muß erstmal neuer Speicher reserviert werden, dann wird der Inhalt des alten Speichers rüberkopiert und danach dieser freigegeben.
Nun ist entsteht hier aber an den alten Speicherstellen eine Lücke, welche kleiner ist, als der nächste zu reservierende Speicher, weswegen dieser da nicht reinpaßt und er somit nicht nutzbar ist.
Im Endefekt hat man zwar selber genausoviel Speicher #### genutzt, aber es bleibt auch noch viel Ungenutzer --- übrig.
Hier muß man auch noch beachten, daß der Delphispeichermanager Speicher in Blöcken/Gruppen bei Windows anfordert und diesen stückchenweise an unsere Programme abgibt.
Diese Blöcke/Gruppen können aber nur an Windows zurückgegeben werden, wenn alle Einzelteil wieder vom Programm freigegeben wurden.
Heißt also, von Seiten des Windows ist der ganze Block benutzt, selbst wenn das Programm nur einen Bruchteil davon verwendet.
Und jetzt stell dir vor, daß es nicht nur diesen einen(zwei) Teile gibt, sondern Viele und das da schonmal viele Lücken entstehen können.