Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Speicherfresser -> .Free (https://www.delphipraxis.net/14696-speicherfresser-free.html)

Morfio 14. Jan 2004 09:52


Speicherfresser -> .Free
 
Hi,

ich schreibe gerade eine Applikation, bei der ich ein paar Objekte erstelle. Ich mache an jedem Ende einer Prozedur, in der ich das Objekt erstellt habe, ein Objekt.Free.

Dennoch zieht Windows immer und immer weiter Speicher. Woran könnte das liegen?

Vielen Dank,

Morfio ...

PS: Dazu sollte ich unter Umständen noch sagen, dass ich immer wieder die selbe Prozedur ausführe, wenn ich worauf klicke, also in etwa so:

Delphi-Quellcode:
procedure IchWerdeAusgefuehrt;
var variable ...
begin
  Objekt = TObjekt ...
  variable = Objekt.MachWas ...
  Objekt.Free
end


procedure Click;
begin
  IchWerdeAusgefuehrt;
end
Immer und immer wieder zieht er sich 200kb beim Klicken auf Click.

[edit=sakura] [code] durch [delphi] ersetzt. Mfg, sakura[/edit]

Phoenix 14. Jan 2004 10:07

Re: Speicherfresser -> .Free
 
Hi.

1.) Könntest Du anstelle des Zitats vielleicht die Code - Tags benutzen? Dann kann man den Codeschnipsel besser lesen ;-)

2.) Bist Du Dir sicher, daß das Objekt.Machwas nicht vielleicht irgend ein anderes Objekt instanziert und das nicht freigibt?

Morfio 14. Jan 2004 10:15

Re: Speicherfresser -> .Free
 
Also,

ich benutze innerhalb des Objektes die mySQL.pas-Klasse (diese kostenlose). Ich bin momentan am Ausklammern und habe festgestellt, dass innerhalb der Klasse meines Objekts Variablen anscheinend nicht entladen werden. Sobald ich in

Delphi-Quellcode:
_myRes := mysql_store_result(_myCon);
schreibe, zählt der schon 32kb immer und immer wieder hoch. Kann bzw. muß man solche Variablen per Hand wieder aus dem Speicher entfernen? Ich dachte immer, das macht Objekt.Free? Ich paste mal die Methode hier rein:

Delphi-Quellcode:
function TAdressen.Adresse(Where, Tables: String): AdressenArr;
var
   query: String;
   _myRes: PMySql_Res;
   _myRow: PMySql_Row;
   Items: Integer;
   i: Integer;
   Cols: Integer;
begin
   if Tables <> '' then Tables := ', ' + Tables;
   query := 'SELECT ' +
   {0}         'Adressen.AdressenID AS id, ' +
   {1}         't2.Bereich AS Bereich, ' +
   {2}         'Adressen.Name AS Name, ' +
   {3}         'Adressen.Zusatz AS Zusatz, ' +
   {4}         'CONCAT(t1.Strasse," ",t1.Hnr) AS StrasseNr, ' +
   {5}         't1.Plz AS Plz, ' +
   {6}         't1.Ort AS Ort, ' +
   {7}         'Adressen.Telefon AS Telefon, ' +
   {8}         'Adressen.Fax AS Fax, ' +
   {9}         'Adressen.eMail1 AS eMail1, ' +
   {10}      'Adressen.Internet AS Internet, ' +
   {11}      't3.Bundesland AS Bundesland, ' +
   {12}      't4.Land AS Land, ' +
   {13}      't1.Strasse AS Strasse, ' +
   {14}      't1.Hnr AS Hnr, ' +
   {15}      't1.Postfach AS Postfach, ' +
   {16}      't1.Postfach_Plz AS Postfach_Plz, ' +
   {17}      't1.Postfach_Ort AS Postfach_Ort, ' +
   {18}      'Adressen.eMail2 AS eMail2, ' +
   {19}      't5.Inhalt AS Notizen, ' +
   {20}      't6.Inhalt AS Informationen, ' +
   {21}      'Adressen.OnlineVeroeffentlichung AS OE, ' +
   {22}      'Adressen.BereichZuweisung AS Zuweisung ' +
            'FROM Adressen ' +
            Tables + ' ' +
            'INNER JOIN Adresse AS t1 ON Adressen.Adresse = t1.AdresseID ' +
            'INNER JOIN Bereiche AS t2 ON t2.BereichID = Adressen.Bereich ' +
            'LEFT JOIN Bundeslaender AS t3 ON t3.BundeslandID = t1.Bundesland ' +
            'LEFT JOIN Laender AS t4 ON t4.LaenderID = t1.Land ' +
            'LEFT JOIN Texte AS t5 ON t5.TexteID = Adressen.Informationen ' +
            'LEFT JOIN Texte AS t6 ON t6.TexteID = Adressen.Notizen ' +
            Where;
   Cols := 23;
   mysql_real_query(_myCon, PChar(query), Length(query));
   _myRes := mysql_store_result(_myCon);
   if _myRes <> nil then
   begin
      Items := mysql_num_rows(_myRes);
      SetLength(Result, 1, Cols);
      if Items >= 0 then
      begin
         SetLength(Result, Items, Cols);
         for i := 0 to Items - 1 do
         begin
            _myRow := mysql_fetch_row(_myRes);
            Result[i,0] := _myRow[0];
            Result[i,1] := _myRow[1];
            Result[i,2] := _myRow[2];
            Result[i,3] := _myRow[3];
            Result[i,4] := _myRow[4];
            Result[i,5] := _myRow[5];
            Result[i,6] := _myRow[6];
            Result[i,9] := Telefonnummern('Telefon', _myRow[0]);
            Result[i,10] := Telefonnummern('Fax', _myRow[0]);
            Result[i,11] := _myRow[9];
            Result[i,12] := _myRow[10];
            Result[i,7] := _myRow[11];
            Result[i,8] := _myRow[12];
            Result[i,13] := _myRow[13];
            Result[i,14] := _myRow[14];
            Result[i,15] := _myRow[15];
            Result[i,16] := _myRow[16];
            Result[i,17] := _myRow[17];
            Result[i,18] := _myRow[18];
            Result[i,19] := _myRow[19];
            Result[i,20] := _myRow[20];
            Result[i,21] := _myRow[21];
            Result[i,22] := _myRow[22];
         end;
      end
      else
      begin
         SetLength(Result, 0, Cols);
      end;
   end;
Vielen Dank,

Morfio ...

choose 14. Jan 2004 10:23

Re: Speicherfresser -> .Free
 
Ich kenne mich mit dieser Bibliothek nicht aus, es scheint aber, als wenn Du mit
Delphi-Quellcode:
// send query
_myRes := mysql_store_result(_myCon);
// retrieve row
_myRow := mysql_fetch_row(_myRes);
Referenzen auf dynamisch erzeugte Container bekommst. An keiner Stelle kann ich erkennen, dass diese Daten freigegeben werden.
Bitte schlage in der Doku zu dieser Bibliothek nach, ob es analoge Routinen zum Freigeben der Daten (zB mysql_free_result bzw mysql_free_row oä) gibt.
Was passiert mit der Connection _myCon? Gibt es hier vielleicht eine Query-History, so dass die Daten dort "kleben" bleiben?

Chewie 14. Jan 2004 10:28

Re: Speicherfresser -> .Free
 
Also, es gibt ein Gegenstück zu mysql_store_result: mysql_free_result. Ohne das wird der gesamte Ergebnissatz im Speicher behalten.

Zum Schließen der Verbindung wird mysql_close benutzt.

Siehe außerdem mein Tutorial zu diesem Thema (sofern du es nicht schon gelesen hast).

Morfio 14. Jan 2004 10:59

Re: Speicherfresser -> .Free
 
Hi,

vielen Dank, das scheint es (mit free_result) gewesen zu sein. Ich wußte nicht, dass das dann permanent im Speicher bleibt.

Morfio ...

und: :dp: bzw. vor allem die Mitglieder hier (:


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