![]() |
dynamisches Array -> setLength Problem
Hallo,
ich habe ein Problem mit dem Speicher, welches mein Array braucht. 1. Wenn ich von vornerein weiß wie groß mein Array werden soll und dieses im Vorfeld auf die richtige größe setze, wird relativ wenig Speicher gebraucht 2. Wenn ich aber mein Array in der Größe immer um eins erhöhe frißt dieses unmengen von Arbeitsspeicher.
Delphi-Quellcode:
Gibt es eine Möglichkeit mein Array zu reorganisieren und damit den Speicherverbrauch zu senken, ohne das ich die Daten in ein weiteres Array kopieren muß, also in eins wo die größe vor der Befüllung feststeht?
procedure TForm1.setArray; //Testbeispiel
var i: integer; begin //zu 1. setlength(hallo,5,StrToInt(edit1.Text)+1); for i :=0 to strtoint(Edit1.Text) do begin //zu 2. setlength(hallo,5,i+1); hallo[0,i] := 'test12345678 '+ inttostr(i); hallo[1,i] := 'test12345678 '+ inttostr(i); hallo[2,i] := 'test12345678 '+ inttostr(i); hallo[3,i] := 'test12345678 '+ inttostr(i); hallo[4,i] := 'test12345678 '+ inttostr(i); Application.ProcessMessages; Label1.caption := inttostr(i); end; end; Gruß Wegalt |
Re: dynamisches Array -> setLength Problem
Wenn du die Größe eines Arrays änderst, wird der ganze Krams, der vorher in dem Array nicht drin war, an eine andere Stelle im Speicher kopiert. Es kann dabei vorkommen (und es kommt vor), dass der Speicher, den das Array vorher belegte, nicht freigegeben wird. Deshalb der erhöhte Speicherverbrauch.
Man kann diese Effekt minimieren, wenn man immer segmentweise das Array vergrößert, also nicht immer um 1 größer, sondern um einen konstanten Wert (z.B. 100) oder um eine Prozentangabe (z.B. 10%). Das erfordert natürlich einen etwas höheren Verwaltungsaufwand, da High(Array) nicht mehr unbedingt die Obergrenze des Geschriebenen darstellt, aber erhört die Performance und spart Speicherplatz. |
Re: dynamisches Array -> setLength Problem
Zitat:
Zitat:
|
Re: dynamisches Array -> setLength Problem
Das ist mir auch schon eingefallen, ist aber nicht besonders elegant!
Es scheint als würde das Array mit jedem setLength mit der neuen Größe kopiert und das alte nicht nicht wieder frei gegeben wird. Man könnte evtl 2 Arrays benutzen und die Daten immer von einem ins andere kopieren und dann jeweils das ungenutzte leeren. Gefällt mir aber auch nicht! Es wundert mich nur das trotz diesem Problem so viel mit setlength experimentiert wird!! |
Re: dynamisches Array -> setLength Problem
Zitat:
|
Re: dynamisches Array -> setLength Problem
Ich nutze SetLength auch sehr intensiv, habe aber solche Probleme noch nie gemerkt. Das kann mehrere Ursachen haben:
Fehler in der Delphi-Version? Ich nutze Delphi 6.02 Bei mir ist es, ich habe es aber nie gemerkt Wenn die Objekte, wo das Array zugehört, freigegeben werden, so wird der Speicher doch wieder korrekt freigegeben. Letzteres könnte evtl. den Ausschlag geben, wissen tue ich es nicht. Der Großteil der SetLengths ist in meinen Programmen in kurzlebigen Objekte drin... |
Re: dynamisches Array -> setLength Problem
Also Delphi abhängig scheint es nicht zu sein. Ich nutze Delphi 5 und 7.
Grundsätzlich tritt das Problem natürlich nur ab vielen Datensätzen auf. Also wenn man 10tausende einfügt ist der Speicher rats bats voll. Wenn man das Array wieder auf null setzt wurde auch der gesamte Speicher freigegeben. Bei der 2. Version dauert es natürlich um längen länger ihn freizugeben. |
Re: dynamisches Array -> setLength Problem
Durchsucht mal das Forum. Dort haben schon mehrere (mich eingeschlossen) dieses Phänomen erklärt.
Um es kurz zu machen: Konstruktor wie
Delphi-Quellcode:
und
for i := 0 to 100000 do
SetLength(A, Length(a) + 1);
Delphi-Quellcode:
machen im Hintergrund fast genau dasselbe.
for i := 0 to 100000 do
S := S + 'x'; Und gemeinsam haben sie, dass sie den Delphi Speichermanager mishandeln. Dieser reserviert nämlich den Speicher in Blöcken von Windows und wenn FreeMem aufgerufen wird, wird dieser Speicher nur wieder an Windows zurückgegeben, wenn der zusammenhängende Block frei ist. Ansonsten merkt sich der Delphi Speichermanager die Position und die Größe des freigegebenen Speicherbereichs um ihn schneller wieder zur Verfügung zu stellen als es Windows je könnte. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:55 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz