Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Frage zu Out of Memory Error (Ältere Delphi Version) (https://www.delphipraxis.net/213531-frage-zu-out-memory-error-aeltere-delphi-version.html)

TheGroudonx 13. Aug 2023 08:21

Frage zu Out of Memory Error (Ältere Delphi Version)
 
Hi,

Ich habe folgenden einfachen Code den ich in Delphi (Windows) ausführe:

var i : Integer; anArray : Array of String;
for i := 0 to 1000000 do
begin

setLength(anArray, length(anArray) + 1);
anArray[length(anArray) - 1] := intToStr(random(100000000));

end;

Ich frage mich nun, wieso das in einem Out of Memory (Zu wenig Arbeitsspeicher) endet.
Würde Ich stattdessen das array nur einmal auf die Größe 1000000 setzen, gäbe es erstmal keinen solchen Fehler (Das ist aber nicht die gesuchte Lösung hier).

Andreas13 13. Aug 2023 08:56

AW: Frage zu Out of Memory Error (Ältere Delphi Version)
 
Hallo,
bei mir läuft Dein Code ohne jedwede Fehlermeldung.
Vielleicht liegt die Ursache außerhalb der obigen Schleife (verschleppter Fehler, nicht freigegebene dynamische Arrays?)

Bernhard Geyer 13. Aug 2023 09:01

AW: Frage zu Out of Memory Error (Ältere Delphi Version)
 
Sorgt nicht ein SetLength dafür das erst Platz für neue größe (durchgehender Adressraum) geschaffen wird und dann das alte Array dorthin kopiert wird?
D.h. du brauchst auf jedenfall mehr RAM als wenn du direkt die maximale Zielgröße anforderst.
Das zusammen mit den sehr einfach gestrickten MemoryManager von alten Delphis (hier war FastMM4 ein absolute Notwendigkeit) ist das Problem zu erklären.

TheGroudonx 13. Aug 2023 10:16

AW: Frage zu Out of Memory Error (Ältere Delphi Version)
 
Der Fehler tritt definitiv in diesem Code auf, also es liegt nicht an Code der davor ausgeführt werden würde (vlg. hier).
Es ist gut möglich (und hoffentlich der fall), dass es in neueren Delphi Versionen nicht mehr zu diesem Fehler kommt.

Ich nehme an, in einer älteren Version habe Ich dann keine andere Alternative, als auf zu häufiges ändern der Array Größe zu verzichten?

Andreas13 13. Aug 2023 10:29

AW: Frage zu Out of Memory Error (Ältere Delphi Version)
 
Welche Delphi-Version verwendest Du?

Zitat:

Zitat von TheGroudonx (Beitrag 1525558)
..keine andere Alternative, als auf zu häufiges ändern der Array Größe zu verzichten?

Eine brauchbare Krücke wäre, das Array von Anfang an auf die endgültige Grüße zu dimensionieren und nur es nur teilweise zu belegen. Dann müßtest Du selber über die Array-Belegung durch eine weitere Integer-Variable manuell Buch führen. :(

Uwe Raabe 13. Aug 2023 10:33

AW: Frage zu Out of Memory Error (Ältere Delphi Version)
 
Eventuell genügt es, einmal dem Array eine maximale Größe zuzuweisen und dann nur noch kleinere Werte (aber größer als 0) zu setzen. Aber ich kann aktuell auch nicht sagen, ob das in Delphi 7 was bewirkt.

Im Array werden ja auch nur die Pointer auf die Strings gespeichert, die natürlich auch dynamischen Speicherbereich benötigen. Ich vermute, dass dies zu einer Zerstückelung des Speichers führt, bei der dann irgendwann keine großen Blöcke mehr verfügbar sind.

jaenicke 13. Aug 2023 10:58

AW: Frage zu Out of Memory Error (Ältere Delphi Version)
 
Zitat:

Zitat von TheGroudonx (Beitrag 1525558)
Ich nehme an, in einer älteren Version habe Ich dann keine andere Alternative, als auf zu häufiges ändern der Array Größe zu verzichten?

Den Fehler solltest du auch in neueren Delphiversionen vermeiden, da es auch mit der besten Optimierung unvermeidbar deutlich langsamer ist.

Andreas13 13. Aug 2023 11:11

AW: Frage zu Out of Memory Error (Ältere Delphi Version)
 
Ich möchte Sebastian ausdrücklich beipflichten! :thumb:
Seit Delphi 5 verwende ich einen ähnlichen Trick bei der Nullstellen-Suche von Funktionen mit sehr vielen Nullstellen: z. B. Bessel-Funktionen bei der instationären Wärmeübertragung, die je nach Anwendungsfall zwischen 0 und tausenden Lösungen haben können. Um nicht bei jeder neuen Nullstelle das Array mit den Lösungen neu dimensionieren (und intern den Inhalt u. U. stets umkopieren) zu müssen, mach ich z. B. 50-er Sprünge bei
Delphi-Quellcode:
SetLength(..)
. Das ist deutlich schneller und verhindert die noch schlimmere Fragmentierung des Heap. :-D

himitsu 13. Aug 2023 13:06

AW: Frage zu Out of Memory Error (Ältere Delphi Version)
 
Ja, Arrays sind immer zusammenhängend im Speicher.
Bei mehrdimensionalen dynamischen Arrays betrifft das jede Ebene/ParentLevel einzeln. (statische Arrays sind auch über alle Level immer zusammenhängend)

Und ja, wenn das Array der Speicher vergrößert wird, wird jeweils eine völlig neue Kopie erstellt,
also neuer Speicher, Inhalt rüberkopieren und das alte Freigeben.



Ich glaube auch das SetLength wurde später nochmal etwas verbessert, so dass es größere Bereiche neu reservert und dann die nächsten paar Durchläufe nichts machen muß.
Und natürlich der optimalere Speichermanager, aber bei größeren Blöcken gibt es zwischen altem und neuem Manager praktisch keine Unterschiede.

himitsu 13. Aug 2023 13:16

AW: Frage zu Out of Memory Error (Ältere Delphi Version)
 
Unabhängig davon, dass dieses Vorgehen eh bestraft gehört (was die Speicherverwaltung hier übernimmt)
ist es einfach nur schwachsinnig so oft nutzlos den Speichermanager zu beschäftigen.


Du hast also gleichzeitig 1-2 große Speicherblöcke (das Array),
eine Masse an kleinen Speicherblöcken (die vielen Strings)
und zussätzlich noch im Speicher verteilt anderes Zeugs, wie die EXE, DLLs usw.

Wie im alten DelphiMM Speicher verteilt ist ... tja, könnte man mal nachsehn.
https://www.delphipraxis.net/1525208-post13.html
Im aktuellen FastMM ist kleiner und großer Speicher bestimmt aus diesem Grunde möglichst voneinander getrennt.


PS: Die 4-GB-Option (LargeAddressAware) ist auch im alten Delphi nutzbar, aber es ist nicht wirklich die Lösung,
denn das Array ist eigentlich bloß 1000000*SizeOf(Integer)+8 * 2 groß, also lediglich 4 und kurzzeitig 8 MB.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:31 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz