AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Frage zu Out of Memory Error (Ältere Delphi Version)

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

Ein Thema von TheGroudonx · begonnen am 13. Aug 2023 · letzter Beitrag vom 13. Aug 2023
Antwort Antwort
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.378 Beiträge
 
Delphi 12 Athens
 
#1

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

  Alt 13. Aug 2023, 13:06
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.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (13. Aug 2023 um 15:47 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.378 Beiträge
 
Delphi 12 Athens
 
#2

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

  Alt 13. Aug 2023, 13:16
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.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (13. Aug 2023 um 15:26 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.378 Beiträge
 
Delphi 12 Athens
 
#3

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

  Alt 13. Aug 2023, 15:47
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ß.
Vielleicht war es auch nicht im SetLength selber, sondern im ReallocMem, aber egal.

Delphi-Quellcode:
{$POINTERMATH ON}
{$OVERFLOWCHECKS OFF}

procedure TForm4.FormShow(Sender: TObject);
var
  TheArray: array of string;
  ThePointer: Pointer;
  ReallocCount, ResizeCount, RealSize, i: Integer;
  Start: Cardinal;
begin
  Assert(SizeOf(Pointer) = 4);
  ReallocCount := 0;
  ResizeCount := 0;
  ThePointer := 0;
  RealSize := 0;
  Start := GetTickCount;
  try
    for i := 0 to 1000000 do begin
      SetLength(TheArray, Length(TheArray) + 1);
      TheArray[Length(TheArray) - 1] := IntToStr(Random(100000000));

      if ThePointer <> Pointer(TheArray) then begin
        ThePointer := Pointer(TheArray);
        Inc(ReallocCount);
      end;
      if RealSize <> (PInteger(TheArray) - 1)^ then begin
        RealSize := (PInteger(TheArray) - 1)^;
        Inc(ResizeCount);
      end;
    end;
  except
    Memo1.Lines.Add(Format('BREAK'#13#10'Length = %d'#13#10'%d Reallocs'#13#10'%d ResizeCount'#13#10
      + '%d ms', [Length(TheArray), ReallocCount, ResizeCount, Integer(GetTickCount - Start)]));
    raise
  end;
  Memo1.Lines.Add(Format('%d Reallocs'#13#10'%d ResizeCount'#13#10'%d ms',
    [ReallocCount, ResizeCount, Integer(GetTickCount - Start)]));
end;
aktuelle 11.3:
Code:
27 Reallocs
1000001 ResizeCount
47 ms

[edit]
Ja, grad bemerkt, ResizeCount muß 1000001 sein.
Hier müsste man besser auf die Größenangabe des Speicherblocks zugreifen, oder AllocMem/FreeMem/ReallocMem hooken.
Beim Hook sind dann aber auch die Strings mit enthalten
und die Größenangabe ist bei beiden Speichermanagern unterschiedlich hinterlegt. (kann auf die schnelle eh nicht nachsehn, wie es im alten Delphi MM war)

Versuch: (nicht wundern, dass es etwas langsam ist ... hier nur 13 Sekunden)
Delphi-Quellcode:
{$POINTERMATH ON}
{$OVERFLOWCHECKS OFF}

procedure TForm4.FormShow(Sender: TObject);
var
  TheArray: array of string;
  ThePointer: Pointer;
  ReallocCount, ResizeCount, RealSize, i: Integer;
  Start, Allocated: Cardinal;
begin
  Assert(SizeOf(Pointer) = 4);
  ReallocCount := 0;
  ResizeCount := 0;
  ThePointer := 0;
  RealSize := 0;
  Start := GetTickCount;
  try
    for i := 0 to 1000000 do begin
      Allocated := GetHeapStatus.TotalAllocated;
      SetLength(TheArray, Length(TheArray) + 1);
      Allocated := GetHeapStatus.TotalAllocated - Allocated;

      TheArray[Length(TheArray) - 1] := IntToStr(Random(100000000));

      if ThePointer <> Pointer(TheArray) then begin
        ThePointer := Pointer(TheArray);
        Inc(ReallocCount);
      end;
      if {RealSize <> (PInteger(TheArray) - 1)^} Allocated <> 0 then begin
        RealSize := (PInteger(TheArray) - 1)^;
        Inc(ResizeCount);
      end;
    end;
  except
    Memo1.Lines.Add(Format('BREAK'#13#10'Length = %d'#13#10'%d Reallocs'#13#10'%d ResizeCount'#13#10
      + '%d ms', [Length(TheArray), ReallocCount, ResizeCount, Integer(GetTickCount - Start)]));
    raise
  end;
  Memo1.Lines.Add(Format('%d Reallocs'#13#10'%d ResizeCount'#13#10'%d ms',
    [ReallocCount, ResizeCount, Integer(GetTickCount - Start)]));
end;

PS: siehe System.pas -> DynArraySetLength
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (13. Aug 2023 um 16:06 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:18 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