Autor Beitrag
Flamefire
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Sa 20.09.08 19:59 
Hallo,
habe folgendes:
Ich benutze die Struktur, die wir hier erstellt haben: Klick
Im wesentlichen also:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
constructor TOrdner.Create(const AName: String = ''; AOwner: TOrdner = NIL);
begin
  inherited Create;
  FName := AName;
  FOwner := AOwner;
  FOrdner := TObjectlist.Create;
  FDateien := TStringList.Create;
  if Assigned(FOwner) then
    FOwner.Ordner.Add(Self);
end;
destructor TOrdner.Destroy;
begin
  FreeAndNil(FDateien);
  FreeAndNil(FOrdner);
  inherited;
end;

procedure TOrdner.Free(ARemove:Boolean=false);
begin
  If(self<>nilthen begin
    If ARemove and (FOwner<>nilthen FOwner.FOrdner.Extract(self);
    Destroy;
  end;
end;


Jetzt lasse ich in einem eigenen Thread das ganze füllen (verschiedene Ordner und dateien in die Listen darunter...)
Dann übergebe ich das ganze mittels Synchronize an eine weitere Klasse.
Von:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
procedure TSuchThread.SyncFertig;
begin
  FFertig:=true;
  SyncStatus;
  FSyncFertig(FOrdner);//Hier die Übergabe. FOrder:TOrdner;
end;

Nach:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
procedure TAufgabe.SourceScanFertig(AOrdner:TOrdner);
begin
  FOSource.Free();//FOSource:TOrdner
  FOSource:=AOrdner;
end;

Dabei bemerke ich, dass nach mehrmaligem Ausführen des Suchvorgangs der Speicher, den das Programm benutzt wächst.
Sollte aber nicht sein.
Wenn ich das mache:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
procedure TAufgabe.SourceScanFertig(AOrdner:TOrdner);
begin
  AOrdner.Free();
end;

Ist alles i.o.
Also ist diese Struktur das Problem. Aber warum? Ich gebe sie doch frei und setze die dann neu.

Jmd Ideen?
Flamefire Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Mi 24.09.08 09:29 
Keiner ne Idee was da sein könnte?
Es wird doch kein weiterer speicher verbraucht beim "kopieren" der TOrdner struktur, da ja nur der pointer kopiert wird.

Ich versteh das nicht... :?!?: :?!?: :?!?: :crying:
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: Mi 24.09.08 16:39 
Also ich kann Anhand der kleinen Codestückchen wirklich nur raten. Aber ich denke mal sehr stark, dass die Instanz AOrdner die an SourceScanFertig übergeben wird, irgendwie übrig bleibt. Du sagst ja selber, dass kein Speicherloch entsteht, wenn AOrdner direkt in SourceScanFertig gelöscht wird. Allerdings, wenn du FOSource freigibst und dann AOrdner zuweist, dann entsteht eines. Mit dem ersten Freigeben wird ja nur die Instanz gelöscht die vorher auf FOSource zugewiesen wurde. Und wenn du dann eine neue auf FOSource zuweist, dann existiert die so lange weiter bis auch diese gelöscht wird. Und wenn du FOSource beim Freigeben der TAufgabe Instanz nicht mit freigibst, dann bleibt sie erhalten.

Du kannst/solltest dir auch mal FastMM4 anschauen. Der hat neben einem verbesserten Speichermanager auch noch die Möglichkeit sich Speicherlöcher anzeigen zu lassen. So würdest du sofort sehen ob was übrig geblieben ist und vor allem was und wo es erstellt wurde.

Ich denke das wurde dir vermutlich schon mal gesagt, aber ich tue es trotzdem noch mal. Deutsche Bezeichner an sich ja schon schlimm aber in einem Bezeichner Deutsch und Englich zu mischen übertrifft das noch. Das ist echt schon ein bisschen grusselig. :P

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
Flamefire Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Mi 24.09.08 17:11 
Ja zugegeben meine bezeichner sind seltsam...aber was solls...ich komm damit klar ^^
mal zur veranschaulichung:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
//Anfangsinitialisierung der Aufgabe
FOSource:=nil;

//programm läuft
...
//thread wird gestartet
    FSuchSource:=TSuchThread.Create(FSSource,1,SourceScanFertig);
...
//Thread wird fertig
procedure TAufgabe.SourceScanFertig(AOrdner:TOrdner);
begin
  FOSource.Free();
  FOSource:=AOrdner;
end;
//Noch ist alles in Ordnung. Thread wird freigegeben...

...

//Thread nochmal starten
    FSuchSource:=TSuchThread.Create(FSSource,1,SourceScanFertig);
...
//Thread wird fertig
procedure TAufgabe.SourceScanFertig(AOrdner:TOrdner);
begin
  FOSource.Free();//Alten Ordner löschen
  FOSource:=AOrdner;//Neuen Übernehmen
end;
-->Speicher leak!

Das ist jetzt kein code sonder der prinzipielle ablauf.

Also: Den alten Ordner gebe ich frei und nehme den neuen. Es existiert also immer ein Ordner-Objekt (nur beim start existiert keins)
Da die Daten immer gleich sind (es wird das gleiche Verzeichnis eingelesen) sollte sich der verwendete speicher nicht erhöhen.
tut er aber.
Hab mit eurekalog schonma versucht, da was zu finden, aber zeigt nix an.
anzeigen tut er aber was nach "AllocMem(10000)"; also hat es funktioniert.

ich sehe einfach nichts was das verursachen könnte
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: Do 25.09.08 09:14 
Also Anhand von dem Pseudocode/Schema kann man nicht sagen ob das richtig ist. Denn ich für meinen Teil weiß nicht wie lange die TAufgabe gültig ist und was mit dem zugewiesenen FOSource passiert. Wenn du beim Freigeben von TAufgabe das FOSource nicht löscht, dann hast du ein Speicherloch. Wenn du es doch löscht, dann sollte keines existieren.

Wenn du bereits einen Speichertester deines Vertrauens hast laufen lassen und der keinen Fehler angezeigt hat (obwohl Delphi von Hause aus eigentlich immer einen Fehler hat), dann wird es an etwas anderem liegen. Wenn Delphi Speicher benötigt, dann wird das in Blöcken von Windows angefordert und auf die aktuelle und folgende Aufgaben verteilt. Solch ein Block kann natürlich nur dann freigegeben werden, wenn alle Referenzen darauf gelöscht wurden. Und wenn zufällig gerade ein delphi interenes Objekt Speicher haben wollte, dann kann es sein, dass obwohl du alles gelöscht hast der Speicherverbrauch im Windows nicht wieder runter geht. Das ist sogar nicht selten der Fall, weswegen der Speicherverbrauch im Windows nicht zum Feststellen von Löchern brauchbar ist. Sondern nur dafür wie viel deine Anwendung wirklich beanschlagt.

Was du machen kannst ist mal ein Stresstest. Also nicht 1-2 Verzeichnisse einlesen sondern 100-200. Also das geht dann auch nur automatisiert. Und wenn der Speicherverbrauch dann kontinuierlich ansteigt, dann solltest du mal das von mir erwähnte FastMM4 ausprobieren. Erwarte aber auch da nicht, dass der Speicherverbrauch wieder auf den Anfang zurück geht. Selbst ein Objekt was noch so klein ist kann einen Speicherblock als benutzt markieren. Wenn du pech hast kann dir das auch bei mehr als nur einem Block passieren.

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
Flamefire Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Do 25.09.08 10:31 
Als Stresstest habe ich den windows ordner einlesen lassen. (ca 4000 Ordner)
und dass 100 mal
nach verschiedenen anpassungen (wie explizitem setzen von FOrdner=nil; im destructor des threads) stelle ich das fest, was du gesagt hast: der speicherverbrauch geht hoch bis auf einen bestimmten punkt und schwankt dann dort (+-100b)
sieht also so aus, als wäre das problem gelöst.
vielen dank.