![]() |
Memory Leak bei rekursiven Aufruf...
Hallo, ich fuehre in unserer ISAPI eine rekursive Suche in der Datenbank nach den Vorfahren von eines mir angegebenen Tiers durch.
Bei dem rekursiven Procedur Aufruf gebe ich ein TStrings Object mit, was meines Wissens nach ja nur eine Referenz auf das TString Object ist. Das TString Objekt wird nur einmal am Anfang erstellt und dann in der Funktion mitgegeben. Er erkennt den Anfang dadurch dass ich einen leeres (NIL) TString Object mitliefere. Die Web Application laeuft einwandfrei unter IIS 6.0. Aber nach der mehrmaligen Suche ist mir aufgefallen dass der Server unmengen an Speicher alloziert hat und nach dem Programm Lauf nicht mehr freigibt. Erst wenn ich den IIS resette habe ich wieder 800 MB mehr speicher! Beim Programmlauf selber wird der Speicher auch verbraucht. Wo habe ich hier den Denkfehler?
Delphi-Quellcode:
procedure XXX.InbreedCheck(CheckAnimalsKey: String; PedigreeList: TStrings);
var StartNode: Boolean; AnimalList: TStrings; SireKey, DamKey, s, TempStr: String; begin If PedigreeList = nil then begin StartNode := True; AnimalList := TStringlist.create; ... end else begin StartNode := False; ... Hole Daten fuer SireKey und DamKey end; TempStr := CheckAnimalsKey + '|'; If SireKey <> '' then begin TempStr := TempStr + SireKey + '|'; If pos(SireKey, AnimalList.GetText) > 0 then SireKey := ''; end else TempStr := TempStr + '|'; If DamKey <> '' then begin TempStr := TempStr + DamKey + '|'; If pos(DamKey, AnimalList.GetText) > 0 then DamKey := ''; end else TempStr := TempStr + '|'; AnimalList.add(TempStr); //Hier startet jetzt die rekursive Suche! If (SireKey <> '') then InbreedCheck(SireKey, AnimalList); If (DamKey <> '') then InbreedCheck(DamKey, AnimalList); If StartNode then begin ... AnimalList.free; ... end; end; |
Re: Memory Leak bei rekursiven Aufruf...
Hallo,
lade dir memcheck runter (google) und probier es aus, indem du die Routine in einem eigenen Programm (nicht Dll) testest. Das "eigene Programm schreiben" könntest du dir über dUnit sparen. Heiko |
Re: Memory Leak bei rekursiven Aufruf...
Hallo Niels,
du solltest PedigreeList außerhalb der rekursiven Methode instanzieren und die Erzeugung von AnimalList entfernen.
Delphi-Quellcode:
Grüße vom marabu
procedure XXX.InbreedCheck(subjectKey: string; PedigreeList: TStrings);
var SireKey, DameKey: string; begin // SireKey := GetSireKey(subjectKey); // DameKey := GetDameKey(subjectKey); if PedigreeList.IndexOf(subjectKey) < 0 then PedigreeList.Add(subjectKey); if (SireKey <> '') then InbreedCheck(SireKey, PedigreeList); if (DameKey <> '') then InbreedCheck(DameKey, PedigreeList); end; |
Re: Memory Leak bei rekursiven Aufruf...
Hallo,
außerdem solltest Du Strings möglichst immer als const übergeben. Das verhindert zwar kein Memory leak, läuft aber performanter. Gruß xaromz |
Re: Memory Leak bei rekursiven Aufruf...
Hi, ich habe jetzt den Ausloeser fuer den riesen Speicherverbrauch gefunden!
Die Zeile in der ich meine TStrings liste auf das Vorkommen eines andere Strings untersuche hat das Problem verursacht:
Code:
Ich habe nun einfach die Ueberpruefung ausgelassen und der Speicher ist immer sauber wieder freigegeben worden!
If pos(SireKey, AnimalList.GetText) > 0 then ...
Hat einer von euch eine Ahnung was der "pos" Befehl intern genau macht und wieso er soviel Speicher reserviert und nicht mehr hergibt! Hat mir jemand vielleicht einen workaround der nicht so viel Speicher frisst? Ist das ein bekanntes Problem? Hat jemand schon etwas aehnliches erlebt oder eine andere Moeglichkeit gefunden das zu umgehen? |
Re: Memory Leak bei rekursiven Aufruf...
Hallo,
das Problem liegt nicht beim Aufruf von Pos() sondern von AnimalList.GetText(). Du solltest statt GetText() besser das Property Text verwenden, denn GetText() fordert neuen Speicher an und gibt einen Verweis darauf als PChar zurück. Die Freigabe dieses Speichers ist Aufgabe des aufrufenden Programmteils. (Siehe auch die Hilfe zu TStrings.GetText().) jkr |
Re: Memory Leak bei rekursiven Aufruf...
Vielen Dank fuer eure Hilfe.
Manchmal sieht man nicht das naheliegendste :wall: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:27 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