Delphi-PRAXiS
Seite 4 von 4   « Erste     234   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   SetLength -> Zu wenig Arbeitsspeicher? (https://www.delphipraxis.net/153654-setlength-zu-wenig-arbeitsspeicher.html)

gammatester 12. Aug 2010 11:14

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
Das ist doch wohl trivial, daß der Speicherbedarf ansteigt, wenn Du Gigabyte-weise davon anforderst. Mir ist nur nicht klar, warum es im zweiten Fall nicht zum Anwachsen kommen soll (weil zu schnell geht?) Irgendwann läufts Du doch wohl in beiden Fällen in die Exception, und dann wird doch hoffentlich abgeräumt!? Wenn keine Exception kommt, ist eh nach 32 Durchläufen Schicht wegen 2^32=0 mod 2^32.

AJ_Oldendorf 12. Aug 2010 11:32

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
ich wollte damit auch nicht sagen, dass es mir unklar ist, warum der Speicher steigt. Klar muss er steigen wenn ich jede Menge anfordere...
Aber warum steigt er im zweiten Beispiel nicht? Das ist die spannende Frage?
Das irgendwann ein Int-Überlauf entsteht ist auch klar. Aber darum gehts hier nicht :-)

Viele Grüße
Alex

Neutral General 12. Aug 2010 11:36

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
Weil du ihn direkt nach dem Reservieren wieder freigibst. Er steigt wahrscheinlich schon, aber er sinkt halt schneller wieder als du gucken kannst...

himitsu 12. Aug 2010 11:37

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
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.

AJ_Oldendorf 12. Aug 2010 11:45

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
Danke Himitsu für deine Erklärung.
Wenn ich das richtig verstehe, ist es für den Speicherverbrauch egal ob ich vorher Nil bzw. das Setlength(a,0) aufrufe aber für die Struktur im Speicher (Lücken) es besser ist, diese Aufrufe vorher zu machen.

Gruß
Alex

angos 12. Aug 2010 13:19

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
Zitat:

Zitat von xZise (Beitrag 1041224)
Moin,
Zitat:

Zitat von angos (Beitrag 1041206)
[...]Achja, was mir mal aufgefallen war:

SetLength(ArrayEinesTyps, 2);

rufe ich das einmal auf, so wird der Speicher einmal für zwei ArrayEintraege belegt.
Rufe ich das nochmals auf, so wird ungenutzter Speicher dafür neu belegt, der alte aber nicht freigegeben, laut Taskmanager bleibt der RAM genutzt. [...]

Bist du dir da sicher? Ich behaupte mal so, dass sogut wie keiner das alte Array "freigibt". Und MemoryLeaksOnShutdown meldet da ja auch nichts. Aber ich teste es einfach mal.

[...]

MfG
Fabian


Hi,

ich hatte dieses Problem öfters mit Record-Arrays kann dir aber auch so nicht sagen, wie das Problem genau zustande gekommen ist.
Ich nutze halt seit dem, wenn ich noch mit arrays arbeite zusätzlich einfach das SetLength(x, 0); mittlerweile aus Gewohnheit.
Vielleicht liegt es an den Records oder an bestimmten Datentypen im Record?!

Gruß
angos

xZise 18. Aug 2010 09:34

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
Zitat:

Zitat von AJ_Oldendorf (Beitrag 1041512)
Danke Himitsu für deine Erklärung.
Wenn ich das richtig verstehe, ist es für den Speicherverbrauch egal ob ich vorher Nil bzw. das Setlength(a,0) aufrufe aber für die Struktur im Speicher (Lücken) es besser ist, diese Aufrufe vorher zu machen.

Gruß
Alex

Naja das kommt aber auch auf die Verwendung drauf an. Wenn du das Array nämlich nur verlängern willst, dann kannst du das nicht machen.

Und wie du siehst angos kommt es bei mir zu keiner Änderung der Speichergröße, weil der Speichermanager wohl intelligent genug ist, und immer den gleichen Speicherblock nutzt.

Zitat:

Zitat von Neutral General (Beitrag 1041509)
Weil du ihn direkt nach dem Reservieren wieder freigibst. Er steigt wahrscheinlich schon, aber er sinkt halt schneller wieder als du gucken kannst...

lol? Er steigt aber (eigentlich) insgesamt. Also danach müsste er mindestens doppelt so viel belegen, weil das ganze Array ja nochmal rein muss. Das heißt kurzzeitig ist es auf 0 Byte Verbrauch durch das array, aber dann sofort auf das doppelte von vorher.

MfG
Fabian


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:08 Uhr.
Seite 4 von 4   « Erste     234   

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-2025 by Thomas Breitkreuz