![]() |
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.ä.
|
AW: SetLength -> Zu wenig Arbeitsspeicher?
Hi,
Zu der 2GB/4GB Problematik hier ein vielleicht noch interessanter Artikel: ![]() 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ß |
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. |
AW: SetLength -> Zu wenig Arbeitsspeicher?
Moin,
Zitat:
So, also mit folgenden Code bleibt der RAM Verbauch konstant bei 44 MiB (und dabei ist das Array selber schon ![]()
Delphi-Quellcode:
Ü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).
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; MfG Fabian |
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 |
AW: SetLength -> Zu wenig Arbeitsspeicher?
Zitat:
Delphi-Quellcode:
Das wirst du sehen wie die RAM Auslastung steigt und steigt :P
var
x : TForm; begin while True do x := TForm.Create(nil); end; MfG Fabian PS: Für TForm kannst du ein beliebiges Objekt nehmen, welches nicht automatisiert freigegeben wird. |
AW: SetLength -> Zu wenig Arbeitsspeicher?
Hier mal das reine Defragmentierungsproblem
Delphi-Quellcode:
[]add
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.
Delphi-Quellcode:
ist noch besser, denn es erzeugt kein "echtes" Speicherloch, da kurz vor Programmende der Owner für's Aufräumen sorgt, :roll:
while True do
TForm1.Create(self); aber wärend des Programmablauf's wirkt sich dieses wie ein Speicherleck aus. |
AW: SetLength -> Zu wenig Arbeitsspeicher?
Zitat:
MfG Fabian |
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 |
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:
Hier ist laut TaskManager ganz eindeutig zu sehen, dass der Speicher anwächst.
var
i: Integer; a: AnsiString; begin try i := 1; while True do begin SetLength(a, i); i := i * 2; end; except //DoAnything... end; end. Jetzt eine kleine Änderung und man sieht im TaskManager den Speicher nicht mehr ansteigen...
Delphi-Quellcode:
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.
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. 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 |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:08 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