Delphi-PRAXiS

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)

AJ_Oldendorf 11. Aug 2010 11:31

SetLength -> Zu wenig Arbeitsspeicher?
 
Hallo zusammen,
laut Suchfunktion bin ich ja nicht der erste der das Problem hat.
Ich habe das Problem, dass wenn meine Anwendung lange läuft (paar Tage), dass irgendwann sporadisch bei folgenden Aufruf

Delphi-Quellcode:
var
  aLaenge : Integer;
begin
  aLaenge := 77; //Beispiel

  try
    SetLength(InputMsg^, 12+aLaenge);
  except
    on E: Exception do
    begin
      ErrorStr := 'Aufruf von SetLength():';
    end;
  end;
end;
eine Exception entsteht mit "zu wenig Arbeitsspeicher".
Es ist aber noch genug Speicher verfügbar laut TaskManager (auch virtueller Speicher).
Die Frage ist, wie kann sowas entstehen bzw. wie kann man dies evtl. verbessern / abändern?
Ich verwende Delphi 2009 und die Anwendung läuft auf Win2003 Server.

Wäre für jeden Tip dankbar.

Viele Grüße
Alex

PS: InputMsg wird als PAnsiString in diese Funktion übergeben...

Neutral General 11. Aug 2010 11:37

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
Hallo,

Ist die neue Länge des Strings abhängig von seiner alten Länge? d.h. benutzt du Length um die neue Länge zu bestimmen? Und bist du dir sicher, dass du einen gültigen PAnsiString übergibst?

himitsu 11. Aug 2010 11:40

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
Delphi kann, bzw. Win32-Anwendungen können standardmäßig nur maximal 2 GB an "virtuellem" Speicher verwalten ... ist der voll, dann knallt's

Ich vermute mal du hast ein Speicherleck, durch dein Rumgepointere oder Anderswo.


Scheib mal
Delphi-Quellcode:
ReportMemoryLeaksOnShutdown := True;
in den Constructor deiner Form.

hoika 11. Aug 2010 11:41

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
Hallo,

ich sehe keine Funktion, nur etwas Code.
Und der reicht nicht (Laenge nicht definiert).


Heiko

AJ_Oldendorf 11. Aug 2010 11:45

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
also die Variable ist defintiv gültig.
@hoika, das müsste aLaenge heißen in dem Code (habs geändert).
Ist ja auch nur der Inhalt der Funktion (ohne Funktionskopf).
Kann man an diesen "maximal 2 GB" etwas machen oder kommt man da nicht rum?
Was ist, wenn die Anwendung aber mit der Zeit immer mehr Daten im Bauch halten muss?

Gruß
Alex

freak4fun 11. Aug 2010 11:49

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
Zitat:

Zitat von AJ_Oldendorf (Beitrag 1041110)
Was ist, wenn die Anwendung aber mit der Zeit immer mehr Daten im Bauch halten muss?

Dann bekommt deine Anwendung und du Bauchschmerzen und du musst dein konzept eventuell überdenken. :)

mleyen 11. Aug 2010 11:51

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
Zitat:

Zitat von AJ_Oldendorf (Beitrag 1041110)
Was ist, wenn die Anwendung aber mit der Zeit immer mehr Daten im Bauch halten muss?

Dann lager zwichenzeitlich Daten auf der Festplatte aus.

AJ_Oldendorf 11. Aug 2010 11:53

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
Ok verstehe ich aber das kann ja wohl keine Lösung sein oder?
Ich sag mal ganz krass, wenn ich viele Stringlisten mit vielen Objekten oder Zeigern habe, dann ist es doch keine Lösung "einfach" bei 2GB den Riegel vor die Tür zu schieben wenn mein Rechner doch 4GB hat...
Macht doch kein Sinn oder?

Gruß
Alex

AJ_Oldendorf 11. Aug 2010 11:54

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
ist der verfügbare Speicher evtl. "nur" fragmentiert? kann man da vielleicht ansetzen und irgendwas machen?

Neutral General 11. Aug 2010 11:56

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
Zitat:

Zitat von AJ_Oldendorf (Beitrag 1041114)
Ok verstehe ich aber das kann ja wohl keine Lösung sein oder?
Ich sag mal ganz krass, wenn ich viele Stringlisten mit vielen Objekten oder Zeigern habe, dann ist es doch keine Lösung "einfach" bei 2GB den Riegel vor die Tür zu schieben wenn mein Rechner doch 4GB hat...
Macht doch kein Sinn oder?

Gruß
Alex

Doch macht es. Die anderen 2GB werden mehr oder weniger vom Betriebssystem benötigt. Ich glaube es gibt sogar irgendeinen Tick mit dem man auf 3GB oder so aufstocken kann, aber im Normalfall ist es wirklich so, dass man damit gut auskommen sollte. Wenn du nicht damit auskommst, dann solltest du tatsächlich deinen Code überdenken.

Also wenn ich ein Programm im Taskmanager sehen würde, was 2GB Speicher verbraucht, dann wär das aber ganz schnell abgeschossen....

himitsu 11. Aug 2010 11:56

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
PS: Speicherdefragmentierung gibt's auch noch.

du hast z.B.
- maximal 2 GB virtuellen Speicher verfügbar
- gnügend physischen RAM + Auslagerungsdatei
- aber einen voll defragmentierten virtuellen Speicher (es liegen da ja auch noch über DLLs und so'n Zugs rum)

Wird ein dyn. Array in seiner größe geändert, dann wird/muß eventuell das Array umkopoert werden, weil es nicht Inplace vergrößert werden kann (liegt schon was Anderes dahinter).

Nun brauchst du also:
a) irgendwo ein Stückchen freien Speicher, wo die neuen Arraydaten reinpassen
b) zwischenzeitlich auch mal bis zu doppelt soviel Speicher für das Array (neuer + alte Daten)


[add]
ich sage standardmäßig.

Und es sind etwa 3,75 GB an virtuellen RAM, den Rest kann man mit 32 Bit nicht verwalten und eingige Bereiche wurden wohl aus Kompatibilitätsgründen (zur 31-Bit-signed-Adressierung) gesperrt.

Mein Windows 32 Bit stellt z.B. nur 3,24 zur Verfügung (Integergrenzen und so) und der Rest wird entweder für Treiber werwendet und alles über 4 GB ist eh nicht adressierbar (abgesehn vom LAA / Large-Address-Aware, aber das muß aktiviert sein, das OS muß es unterstützen und deine Anwendung müßte es selbst behandeln)

AJ_Oldendorf 11. Aug 2010 12:08

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
hab mir schon sowas gedacht... kannst du vielleicht trotzdem mal wegen dem trick den du angesprochen hast nachgucken?
ich gucke mal, ob man irgendwelche daten wirklich auslagern kann.
danke und viele grüße
Alex

AJ_Oldendorf 11. Aug 2010 12:11

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
ok, meinte eigentlich auch, dass der Rechner zwar 4GB hat aber ja nur bis max. 3,5 (ca.) adressierbar sind.
Kann mann denn den Speicher irgendwie zur Laufzeit der Anwendung deframentieren? Sicherlich nicht oder?

Viele Grüße
Alex

Bernhard Geyer 11. Aug 2010 12:15

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
Zitat:

Zitat von AJ_Oldendorf (Beitrag 1041126)
ok, meinte eigentlich auch, dass der Rechner zwar 4GB hat aber ja nur bis max. 3,5 (ca.) adressierbar sind.

Ein 32-Bit prozess hat normalerweise nur 2GB zur Verfügung. 3GB mit entsprechenden compilerschalter ({$SetPeFlags $20}) wenn auch das OS mitspielt (64-Bit Windows immer, 32-Bit je nach Boot-Option.

Zitat:

Zitat von AJ_Oldendorf (Beitrag 1041126)
Kann mann denn den Speicher irgendwie zur Laufzeit der Anwendung deframentieren? Sicherlich nicht oder?

Nein. Du hast mit Delphi ein Unmanaged System das sowas praktisch nicht ermöglicht. In Managed Umgebungen (Java/.NET) wäre sowas möglich (weiß aber nicht ob es implementiert ist).

himitsu 11. Aug 2010 12:20

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
Gegen eine Defragmentierung kann man nicht viel machen, außer Speicheroperationen zu optimieren und seltener Speicher neu reservieren, umzureservieren/freizgeben und z.B. Speicherbplätze wiederzuverwenden.

Defragmentieren geht nicht, denn dann müßtest du im gesamten Programm sämtliche Zeiger kennen, welche auf die zu verschiebenden Teile zeigen (welche du nichtmal alle kennst) auch mit anpassen.


Hast du denn mal nach Speicherlecks geschaut? (Beitrag #3)
Oder installier dir das große FastMM und schau da mal in die MemoryMap (grafische Speichernutzungsübersicht).

DeddyH 11. Aug 2010 12:24

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
Zitat:

Zitat von himitsu (Beitrag 1041131)
Gegen eine Defragmentierung kann man nicht viel machen, ...

Wieso sollte man auch? :angel2:

xZise 11. Aug 2010 12:24

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
Wozu muss man Speicher überhaupt "defragmentieren"? Ich meine eine Festplatte verliert selber doch auch kaum Speicher wenn sie fragmentiert ist? Da geht es doch nur darum, schnell hintereinander darauf zuzugreifen?

MfG
Fabian

mkinzler 11. Aug 2010 12:26

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
Wenn aber kein zusammenhängender Speicherblock der entsprechenden Größe verfügbar ist, kann man auch kein solchen anfordern

himitsu 11. Aug 2010 12:35

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
Speicherblöcke im RAM sind immer zusammenhängend ... Dateien können stückchenweise verteilt sein.

Defragmentieren heißt hier nur, daß zwischen den vielen Speicherblöck viele und eventuell zu kleine Speicherbereiche frei sind, welche man benutzen könnte.

Wenn da z.B. nur 20.000 freie Bereiche a maximal 100 Byte überall verteilt rumliegen, sonst alles voll ist und du aber einen Block mit 1000 Byte benötigst, dann paßt der nirgendwo rein,obwohl insgesamt noch genug frei wäre.



aber hier sollte man erstmal
> nach Speicherlecks ausschau halten
und eventuell
> die Speichermap anschauen, ob es wirklich zu soeiner Defragmentierung kommt

AJ_Oldendorf 11. Aug 2010 13:01

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
Ich werde mir das mal angucken mit den Speicherlecks und Speichermap.
Vielleicht komm ich da ja dahinter...
Glaube aber wirklich, dass es wirklich nur an der Fragmentierung liegt da laut TaskManager eben diese 2GB Grenze gar nicht erreicht wird von der Anwendung!

Viele Grüße
Alex

Neutral General 11. Aug 2010 13:06

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
Also ich denke wenn im Taskmanager weniger als 2GB angezeigt werden (wie viel sinds denn ca.?), dann sind es auch MIT Datenfragmentierung weniger als 2GB und das Problem liegt nicht an der Menge des Arbeitsspeichers, sondern wahrscheinlich wie ich schon vermutet habe, dass der PAnsiString auf Müll zeigt oder du versehentlich eine zu große Zahl an SetLength übergibst.. Z.B. durch eine uninitialisierte Variable o.ä.

angos 11. Aug 2010 14:04

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
Hi,

Zu der 2GB/4GB Problematik hier ein vielleicht noch interessanter Artikel:

Klick mich

Ich würde auch eher auf einen Fehler in deiner Programmierung tippen, wie auch schon von Neutral General erwähnt wurde, oder deine Anwendung benötigt tatsächlich soviel, was dann darauf hinausläuft, dass dein Konzept überarbeitet werden sollte ;)

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.

Lediglich SetLength(ArrayEinesTyps, 0); gibt den Speicher tatsächlich wieder frei.


Seit dem verusche ich entweder, die Array-Längen einmal im Programm definieren zu können, oder Objektlisten zu nutzen.


Gruß

Neutral General 11. Aug 2010 14:36

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
@angos:

Der Artikel ist zwar interessant, aber meiner Meinung nach nicht relevant. Es geht ja hier um virtuellen Speicher. Und bei virtuellem Speicher sind haben die im Artikel genannten Beschränkungen keine Bedeutung.

xZise 11. Aug 2010 14:39

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

So, also mit folgenden Code bleibt der RAM Verbauch konstant bei 44 MiB (und dabei ist das Array selber schon ~ 40 MB groß):
Delphi-Quellcode:
type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    x : array of Integer;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  SetLength(x, 10000000);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  while True do
    Button1Click(nil);
end;
Übrigens wegen der Defragmentierung: Stimmt, naja wer sagt da das man x64 nicht braucht :P Da kann es einen egal sein (sofern die Anwendungd das nutzt).

MfG
Fabian

AJ_Oldendorf 11. Aug 2010 14:55

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
wie hast du das festgestellt, dass der Speicher laut TaskManager nicht freigegeben wird?
Ist dies nur bei einem Array der Fall oder bei jedem Typ?

Viele Grüße
Alex

xZise 11. Aug 2010 14:58

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
Zitat:

Zitat von AJ_Oldendorf (Beitrag 1041232)
wie hast du das festgestellt, dass der Speicher laut TaskManager nicht freigegeben wird?
Ist dies nur bei einem Array der Fall oder bei jedem Typ?

Viele Grüße
Alex

Er verbraucht mehr Speicher ;) Mach mal sowas:
Delphi-Quellcode:
var
  x : TForm;
begin
  while True do
    x := TForm.Create(nil);
end;
Das wirst du sehen wie die RAM Auslastung steigt und steigt :P

MfG
Fabian

PS: Für TForm kannst du ein beliebiges Objekt nehmen, welches nicht automatisiert freigegeben wird.

himitsu 11. Aug 2010 15:05

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
Hier mal das reine Defragmentierungsproblem
Delphi-Quellcode:
program Project8;

{$APPTYPE CONSOLE}

uses
  Types, Windows, SysUtils;

function GetMemSize: Integer;
var
  ms: TMemoryStatusEx;
begin
  ms.dwLength := SizeOf(ms);
  GlobalMemoryStatusEx(ms);
  Result := ms.ullTotalVirtual - ms.ullAvailVirtual;
end;

var
  i: Integer;
  a: TIntegerDynArray;

begin
  ReportMemoryLeaksOnShutdown := True;
  try
    i := 1;
    while True do begin
      WriteLn(Format('a: %0.n    mem: %0.n', [i / 1, GetMemSize / 1]));
      SetLength(a, i);
      i := i * 2;
    end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  ReadLn;
end.
[]add
Delphi-Quellcode:
while True do
  TForm1.Create(self);
ist noch besser, denn es erzeugt kein "echtes" Speicherloch, da kurz vor Programmende der Owner für's Aufräumen sorgt, :roll:
aber wärend des Programmablauf's wirkt sich dieses wie ein Speicherleck aus.

xZise 11. Aug 2010 15:34

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
Zitat:

Zitat von himitsu (Beitrag 1041239)
[...]
Delphi-Quellcode:
while True do
  TForm1.Create(self);
ist noch besser, denn es erzeugt kein "echtes" Speicherloch, da kurz vor Programmende der Owner für's Aufräumen sorgt, :roll:
aber wärend des Programmablauf's wirkt sich dieses wie ein Speicherleck aus.

Und wann soll der Owner zum Aufräumen kommen :stupid:

MfG
Fabian

himitsu 11. Aug 2010 15:44

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
Nach der Exception läuft das, wenn man es z.B. in einen Button-OnClick ausführt, in den VCLeigenen Ereignismethodenaufruf-Try-Except-Schutzblock.

Wenn man danach dann die Hauptform schließt, dann nimmt sie alles mit, sobald die VCL Application freigibt und dieses die Hauptform mitnimmt.


Alles in OnCreate der Form1/Hauptform und bei der Exception nehmen sich die Objekte selber mit (Exception im Constructor löscht das Objekt wieder)
> hier braucht man nichtmal die Schleife, da alles rekursiv

AJ_Oldendorf 12. Aug 2010 10:27

AW: SetLength -> Zu wenig Arbeitsspeicher?
 
@Neutral General: Das mein PAnsiString nicht initialisiert ist oder auf Müll zeigt, würde ich jetzt erstmal für mich ausschließen da das besagte Problem nur sporadisch auftritt und nicht so einfach zu greifen ist.

Ich denke schon die ganze Zeit nach, ob es nicht wirklich "einfach" nur an der Fragementierung liegt.
Habe jetzt mal folgendes getestet:

Delphi-Quellcode:
var
  i: Integer;
  a: AnsiString;
begin
  try
    i := 1;
    while True do
    begin
      SetLength(a, i);
      i := i * 2;
    end;
  except
    //DoAnything...
  end;
end.
Hier ist laut TaskManager ganz eindeutig zu sehen, dass der Speicher anwächst.

Jetzt eine kleine Änderung und man sieht im TaskManager den Speicher nicht mehr ansteigen...

Delphi-Quellcode:
var
  i: Integer;
  a: AnsiString;
begin
  try
    i := 1;
    while True do
    begin
      SetLength(a, 0); //<---- NEU
      SetLength(a, i);
      i := i * 2;
    end;
  except
    //DoAnything...
  end;
end.
Habe mir grade mal ein Programm geschrieben, was mir permanent über MessageQueue Nachrichten an einen Thread schickt mit der Übergabe eines PAnsiString und anschließender Freigabe. Ich teste das ganze jetzt mal nur mit dem SetLength (also ohne vorher das "SetLength(xxx,0)" und gucke mir das mal im TaskManager an.
Ein Timer schickt alle 1,5 sek ein Telegramm an den Thread und dieser macht mit dem Telegramm erstmal gar nichts. Ist für mich nur zum testen...

Habt ihr noch Ideen / Anreize / Vorschläge?

Viele Grüße
Alex

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