Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Ständiges Parsen und Schreiben pumpt Arbeitsspeicher voll (https://www.delphipraxis.net/79373-staendiges-parsen-und-schreiben-pumpt-arbeitsspeicher-voll.html)

torud 21. Okt 2006 10:36


Ständiges Parsen und Schreiben pumpt Arbeitsspeicher voll
 
Hallo Wissende,

ich habe diverse Datendateien, die max. 3kb gross sind. Ich überwache ein Verzeichnis, in dem sich diese Dateien befinden und wenn sich eine Datei ändert wird diese geparst und eine XML-Datei generiert und mehrere Navigations und Verwaltungs-XML´s erstellt. Dabei kann es vorkommen, dass immer alle Dateien geparst werden und dass auch viele (20) Dateien geschrieben werden.

Heute hatte ich das Problem, dass dann nach 2 Stunden auf einem dieser Systeme, welche grosszügig ausgestattet sind, die Meldung kam, dass nicht mehr genügend Arbeitsspeicher zur Verfügung steht. Ich werde nun mal checken, ob ich auch immer die Stringlisten, mit denen ich die Dateien erstelle ordentlich freigebe.

Was kann aber dafür noch der Grund sein?

turboPASCAL 21. Okt 2006 10:52

Re: Ständiges Parsen und Schreiben pumpt Arbeitsspeicher vol
 
Zitat:

Zitat von torud
... werde nun mal checken, ob ich auch immer die Stringlisten, mit denen ich die Dateien erstelle ordentlich freigebe.

Aha...

Zitat:

Zitat von torud
Was kann aber dafür noch der Grund sein

...irgend etwas was nicht freigegeben wurde.?! Was kann man ja schlecht sagen, wir kennen das Programm ja nicht. ;)

torud 21. Okt 2006 11:12

Re: Ständiges Parsen und Schreiben pumpt Arbeitsspeicher vol
 
Es könnte vielleicht auch sein, dass es am Schreiben der Logdatei "lag"...!?

Ich habe das mal komplett abgeklemmt, da die Logdatei schon auf 1,4 mb gewachsen war und bei jedem Prozess in dieser Datei geschrieben wurde, was das Programm gerade gemacht hat. Ich habe das mal erstellt, um zu sehen, wann was gemacht wird. Dies wurde mit einer privaten Stringliste erledigt, welche beim Createn erzeugt und beim Destroyen freigegeben wurde, will sagen, dass diese Liste permanent existent war.

Ich werde mal weiter beobachten, obs nun besser wird. Aber ich kann mir vorstellen, dass das der Grund war...Hat jemand damit Erfahrungen gemacht???

turboPASCAL 21. Okt 2006 11:17

Re: Ständiges Parsen und Schreiben pumpt Arbeitsspeicher vol
 
Hm, eine Vermutung:

... ist es möglich das die Stringliste zu gross geworden ist und diese den Speicher blockiert hat ?

ich selbst mache .log Dateien eigentlich nur mit "writeln()", Grund ist es schreibt sofort und belegt keinen Speicher.

torud 21. Okt 2006 11:25

Re: Ständiges Parsen und Schreiben pumpt Arbeitsspeicher vol
 
tja das weiss ich eben auch nicht, aber eine vermutung ist es wert. vielleicht schreibt hier mal jemand, der sich damit auskennt? werde mal überlegen, ob ich das vielleicht auch später mal über writeln löse.

Also da scheint immer noch ein "Leck" zu sein, denn meine exe verbrauchte bis vor 5 Minuten noch 50 MB Arbeitsspeicher und ist mitlerweile bei 60MB und das in einer Zwischenzeit von 10 Minuten.

Ich dachte bisher, dass Stringlisten, die nur einer Procedure oder Function verwendet werden zwar freigegeben werden müssten, aber diese auch automatisch freigegeben werden , wenn die Procedure oder Funktion beendet wurde...!? :roll:

torud 21. Okt 2006 12:45

Re: Ständiges Parsen und Schreiben pumpt Arbeitsspeicher vol
 
Also ich weiss, dass ihr mich sicher dafür in der Luft zerreissen werdet, aber in fast allen grossen Routinen habe ich vergessen die Stringlisten wieder freizugeben. Dies habe ich nun abgestellt.

Das Ergebnis ist, dass sich das Tool nun so zwischen 10 und 20 MB im Verbrauch von Arbeitsspeicher bewegt. Ich denke, dass das eigentlich ok ist. Grundsätzlich würde mich noch interessieren warum die Listen nicht beim Beenden der Proceduren vom Programm automatisch freigegeben werden und wenn Sie denn noch existent bleiben, warum dann beim nächsten Aufruf der Procedure wieder eine gleiche Liste mit gleichem Namen erstellt werden kann.

Hat das was mit den Speicheradressen zu tun?

semo 21. Okt 2006 12:49

Re: Ständiges Parsen und Schreiben pumpt Arbeitsspeicher vol
 
Zitat:

Hat das was mit den Speicheradressen zu tun?
wenn du dein altes programm geschlossen hast existiert ja der zeiger auf den alten adressraum nicht mehr, die daten liegen dort aber noch. wenn du nun eine neue stringliste erzeugst, wird sie ja in einem neuen adressraum angelegt und du erhälst einen neuen zeiger auf den neuen adressraum.

und noch etwas:
also, eine logdatei in einer stringliste halten?

och nö....
:duck:


Delphi-Quellcode:
procedure WriteToLogFile(s: String);
// -----------------------------------------------------------------------------
// einen Eintrag ins LogFile schreiben
// -----------------------------------------------------------------------------
var
  F: TextFile;
  sTextFileName: String;
begin
  sTextFileName := [b]hierSetztDuEinenDateinamenEin[/b];

  AssignFile(F, sTextFileName);

  if not fileExists(sTextFileName) then
    Rewrite(F)
  else
    Append(F);

  Writeln(F, FormatDateTime('dd.mm.yyyy hh:nn:ss:zzz', Now) + ': '+s);
  Flush(F); //Sicherstellen, dass der Text in die Datei geschrieben wird
  CloseFile(F);
end;
noch ein tip: das logfile kannst du dann mit dem tool baretail betrachten,
auch wenn das logfile mehrere mb groß ist.

kolbaschedder 21. Okt 2006 12:58

Re: Ständiges Parsen und Schreiben pumpt Arbeitsspeicher vol
 
Grundsätlich werden alle lokalen Variablen nach Beendigung der Routine freigegeben. So auch deine Stringliste.

var sl : TStringlist;

sl ist aber in Wirklichkeit nur ein Zeiger auf ein TStringlist-Objekt. Es wird also nur der Zeiger, nicht aber das Objekt auf den Der Zeiger zeigt, freigegeben.

Um das zu verdeutlichen, schaun wir uns mal das erzeugen eines Objekts an.

sl := tStringlist.create;

tStringList.create erzeugt ein neues Objekt und liefert eine Referenz(Zeiger) auf das Objekt zurück.
Folgender Code :

sl := tStringlist.create;
sl := tStringlist.create;

erzeugt zwei StringListen. Die erste wird aber für immer verloren sein, da du den Zeiger auf das Objekt verlierst.
folgendes funktioniert :

for i:=0 to 99 do
begin
sl := tStringlist.create;
List.add(sl);
end;

du erzeugst in einer Schleife 100 Stringlisten. die einzelnen Referenzen speicherst du in einem TList-Objekt.

torud 21. Okt 2006 13:16

Re: Ständiges Parsen und Schreiben pumpt Arbeitsspeicher vol
 
@Marcus
Danke für den Tipp mit dem Logfile. Ich werde es von nun an lieber so machen, wie von Dir beschrieben!

@kolbaschedder
Auch Dir vielen Dank für die ausführlichen Erläuterungen. Ich denke, ich habe es nun verstanden. Was ich noch nicht ganz nachvollziehen kann, ist die Tatsache, dass das Tool, welches ja gleichzeitig auf mehreren Clients läuft, auf einem System "nur" 10MB verbraucht und auf einem anderen fetten System runde 20MB. Liegt das an Windows, oder wie kann man das erklären?

Dein Beispiel mit den 100 Stringlisten sollte mir zeigen, dass man zwar ewig viele Stringlisten erstellen kann und diese auch während des Ausführens innerhalb einer Routine den gleichen Namen haben dürfen, aber der Zugriff danach unmöglich ist. Oder?

Namenloser 21. Okt 2006 13:37

Re: Ständiges Parsen und Schreiben pumpt Arbeitsspeicher vol
 
Nein, nur beim ersten Code ist das der Fall.
Beim zweiten werden die Pointer in einer TList gespeichert, sodass du noch darauf zugreifen kannst.


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:27 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