AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Memory Leak bei rekursiven Aufruf...

Ein Thema von Niels14 · begonnen am 1. Nov 2007 · letzter Beitrag vom 13. Nov 2007
Antwort Antwort
Benutzerbild von Niels14
Niels14

Registriert seit: 28. Dez 2005
Ort: Sydney/Australien
18 Beiträge
 
Delphi XE4 Enterprise
 
#1

Memory Leak bei rekursiven Aufruf...

  Alt 1. Nov 2007, 02:54
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;
Niels Maschmeyer
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.275 Beiträge
 
Delphi 10.4 Sydney
 
#2

Re: Memory Leak bei rekursiven Aufruf...

  Alt 1. Nov 2007, 07:13
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
Heiko
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#3

Re: Memory Leak bei rekursiven Aufruf...

  Alt 1. Nov 2007, 07:43
Hallo Niels,

du solltest PedigreeList außerhalb der rekursiven Methode instanzieren und die Erzeugung von AnimalList entfernen.

Delphi-Quellcode:
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;
Grüße vom marabu
  Mit Zitat antworten Zitat
xaromz

Registriert seit: 18. Mär 2005
1.682 Beiträge
 
Delphi 2006 Enterprise
 
#4

Re: Memory Leak bei rekursiven Aufruf...

  Alt 1. Nov 2007, 08:59
Hallo,

außerdem solltest Du Strings möglichst immer als const übergeben. Das verhindert zwar kein Memory leak, läuft aber performanter.

Gruß
xaromz
I am a leaf on the wind - watch how I soar
  Mit Zitat antworten Zitat
Benutzerbild von Niels14
Niels14

Registriert seit: 28. Dez 2005
Ort: Sydney/Australien
18 Beiträge
 
Delphi XE4 Enterprise
 
#5

Re: Memory Leak bei rekursiven Aufruf...

  Alt 13. Nov 2007, 05:37
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:
If pos(SireKey, AnimalList.GetText) > 0 then ...
Ich habe nun einfach die Ueberpruefung ausgelassen und der Speicher ist immer sauber wieder freigegeben worden!
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?
Niels Maschmeyer
  Mit Zitat antworten Zitat
jottkaerr

Registriert seit: 2. Jul 2007
Ort: Tuttlingen
81 Beiträge
 
Delphi 10.1 Berlin Professional
 
#6

Re: Memory Leak bei rekursiven Aufruf...

  Alt 13. Nov 2007, 07:04
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
Jürgen Krämer
Sometimes I think the surest sign that intelligent life exists elsewhere
in the universe is that none of it has tried to contact us. (Calvin)
  Mit Zitat antworten Zitat
Benutzerbild von Niels14
Niels14

Registriert seit: 28. Dez 2005
Ort: Sydney/Australien
18 Beiträge
 
Delphi XE4 Enterprise
 
#7

Re: Memory Leak bei rekursiven Aufruf...

  Alt 13. Nov 2007, 21:52
Vielen Dank fuer eure Hilfe.
Manchmal sieht man nicht das naheliegendste
Niels Maschmeyer
  Mit Zitat antworten Zitat
Antwort Antwort


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 07:00 Uhr.
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