Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Hat die MySQL oder die libmySQL.dll ein Memory Leak? (https://www.delphipraxis.net/76039-hat-die-mysql-oder-die-libmysql-dll-ein-memory-leak.html)

emsländer 29. Aug 2006 08:29


Hat die MySQL oder die libmySQL.dll ein Memory Leak?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Moin,

Ich bin hier schier am verzweifeln. Da ein Dienst, den ich gebastelt habe, mal den Server lahmgelegt hat, habe ich auf den Speicherverbrauch geschaut. Oups ... jeder Aufruf der Datenbank routine kostet 4-16k. Es reicht aus, einfach nur dir Funktion open_fdd und close_fdd aufzurufen. Hier der entsprechende Code:

Delphi-Quellcode:
function open_fdd : PMySQL;
var
  _myCon: PMySQL;      

begin
  result := nil;
  try
    _myCon := mysql_init(nil);
    logdatei('Verbindungsdiscriptor initialisiert','mysql.log');
  except
    _islog := true;
    logdatei('Irgendein Problem ' + mysql_error(_myCon),'mysql.log');
    //beep;
  end;
  if _myCon = nil then begin
    logdatei('Nicht genug freier Speicher, um Verbindungsdeskriptor zu initialisieren','mysql.log');
    Exit;
  end;
  if mysql_real_connect(_myCon, cMySQLhost, cMySQLuser, cMySQLpass, cMySQLdb, cMySQLport, nil, 0) = nil
    then begin
    logdatei('Die Verbindung konnte nicht hergestellt werden. Ursache: ' + mysql_error(_myCon),'mysql.log');
    Exit;
  end;
  result := _mycon;
end;

function close_fdd(_myCon : PMySQL) : boolean;
 var _text : string;
begin
  try
    mysql_close(_myCon);
   logdatei('DB sauber geschlossen','mysql.log');
  except
    _islog := true;
    _text := mysql_error(_myCon);
    logdatei('Fehler beim Schliessen der DB: '+_text,'mysql.log');
  end;
  result := true;
end;
Die Funktion logdatei kann es nicht sein (ich hatte die schon einmal auskommentiert). Aber auch hier mal den Code anbei:

Delphi-Quellcode:
function Logdatei(Text: string; filename : string) : Integer;
var
  LogFile: TextFile;
  TDTempStr: string;
  errorlevel : Integer;
  sDayDir   : string;
  sMonthdir : string;
  sYearDir  : string;
    _sAppDir : string;

begin
  _sAppDir := ExtractFileDir(Application.ExeName);
  errorlevel := 0; // Keine Fehler
  sYearDir := _sAppDir+'\'+dateletters(inttostr(yearof(date)));
  sMonthDir := sYearDir+'\'+dateletters(inttostr(monthof(date)));
  sDayDir  := sMonthDir+'\'+dateletters(inttostr(DayOfTheMonth(date)));
  if _islog then begin
    if not DirectoryExists(sYearDir) then CreateDir(sYearDir);
    if not DirectoryExists(sMonthDir) then CreateDir(sMonthDir);
    if not DirectoryExists(sDayDir) then CreateDir(sDayDir);

    if filename<>'startlog.log' then filename := sDayDir+'\'+filename else filename := _sAppDir+'\'+filename;

    try
      DateTimeToString(TDTempStr, 'dd.mm.yyyy hh:nn:ss', Now());
      TDTempStr := TDTempStr + ': ' + Text;
      AssignFile(LogFile, filename);
      if not (FileExists(filename)) then
      begin
        Rewrite(logfile);
      end else begin
        Append(LogFile);
      end;
      Writeln(LogFile, TDTempStr);
      Flush(LogFile);
      CloseFile(LogFile);
    except
      errorlevel := 1; // Fehler
    end;
  end;
  result := errorlevel;
end;

function dateletters(_in : string) : string;
begin
  _in := trim(_in);
  if length(_in) = 1 then result := '0' else result := '';
  result := result + _in;
end;
Wenn ich mit dem MemoryCheck rangehe, bekomme ich eine Virtual Alloc Meldung (siehe Sceenshot anbei).
Hat da mal jemand eine Idee?

Gruss

EL

RavenIV 29. Aug 2006 08:51

Re: Hat die MySQL oder die libmySQL.dll ein Memory Leak?
 
Die Funktion open_fdd ruft einige andere Funktionen auf.
Evtl ist dort das Speicherloch begraben? Ein guter Kandidat wäre z.B. mysql_init.

Oder Du suchst bei dir in der Applikation nach dem Fehler.
Meistens sind solche Sachen "hausgemacht".

emsländer 29. Aug 2006 08:55

Re: Hat die MySQL oder die libmySQL.dll ein Memory Leak?
 
Zitat:

Zitat von RavenIV
Die Funktion open_fdd ruft einige andere Funktionen auf.
Evtl ist dort das Speicherloch begraben? Ein guter Kandidat wäre z.B. mysql_init.

Oder Du suchst bei dir in der Applikation nach dem Fehler.
Meistens sind solche Sachen "hausgemacht".

Mysql_init ist Bestandteil der MySQL-Lib ...

die andere Funktion (logdatei) ists auf jeden Fall nicht.


Gruss

EL

RavenIV 29. Aug 2006 09:00

Re: Hat die MySQL oder die libmySQL.dll ein Memory Leak?
 
erst mal zum abklären:
ist open_fdd von Dir?

Falls ja, dann könnte es an
Delphi-Quellcode:
_myCon := mysql_init(nil);
liegen. Hier belegst Du Speicher und gibst ihn nicht wieder frei.

emsländer 29. Aug 2006 09:05

Re: Hat die MySQL oder die libmySQL.dll ein Memory Leak?
 
Zitat:

Zitat von RavenIV
erst mal zum abklären:
ist open_fdd von Dir?

Falls ja, dann könnte es an
Delphi-Quellcode:
_myCon := mysql_init(nil);
liegen. Hier belegst Du Speicher und gibst ihn nicht wieder frei.

open_fdd ist von mir.
Allerdings habe ich diese Funktion mehr oder weniger so as it is übernommen. Habe lediglich die Logs dazu gepackt.
Was könnte denn wohl das "Gegenstück" zu mysql_init sein? ... das müsste ich ja dann in close_fdd aufrufen?



Gruss

EL

RavenIV 29. Aug 2006 09:21

Re: Hat die MySQL oder die libmySQL.dll ein Memory Leak?
 
das Pendant zu mysql_init ist laut MySQL-Doku mysql_close.
Zitat:

Zitat von MySQL-Onlinehilfe
mysql_close() schließt eine zuvor geöffnete Verbindung und gibt den Verbindungs-Handle frei, den mysql benutzt hat, wenn der Handle automatisch von mysql_init() oder mysql_connect() zugewiesen worden war.

Das mysql_close rufst Du ja auf in close_fdd. Sollte also passen.

Kann der Fehler doch in einem anderen Programmteil liegen? Vielleicht dort, wo Du das open_fdd/close_fdd aufrufst?

emsländer 29. Aug 2006 09:43

Re: Hat die MySQL oder die libmySQL.dll ein Memory Leak?
 
Zitat:

Zitat von RavenIV
das Pendant zu mysql_init ist laut MySQL-Doku mysql_close.
Zitat:

Zitat von MySQL-Onlinehilfe
mysql_close() schließt eine zuvor geöffnete Verbindung und gibt den Verbindungs-Handle frei, den mysql benutzt hat, wenn der Handle automatisch von mysql_init() oder mysql_connect() zugewiesen worden war.

Das mysql_close rufst Du ja auf in close_fdd. Sollte also passen.

Kann der Fehler doch in einem anderen Programmteil liegen? Vielleicht dort, wo Du das open_fdd/close_fdd aufrufst?

Nein, wenn ich die open/close auskommentiere, wird kein weiterer Speicher gefressen


Gruss

EL

emsländer 29. Aug 2006 12:15

Re: Hat die MySQL oder die libmySQL.dll ein Memory Leak?
 
Hier noch ein paar Ungereimtheiten:

Wenn ich an dem Rechner was mache (Outlook starte, IE starte oder irgendwas anderes), dann geht der Speicherverbrauch dieses Proggies hoch und wird nicht wieder freigegeben.


Der Rechner ist ein vor 5 Tagen frisch aufgesetztes XP Pro SP2 mit allen Hotfixes.
Delphi ist das 2006 Enterprise mit allen Updates.

Das gleiche Leak tritt aber auch an anderen Maschinen auf. So langsam krieg ich einen an der Waffel

Gruss

EL

emsländer 29. Aug 2006 12:46

D2006 scheint ein Speicherleak zu haben!!!
 
Ein Testprogramm:

Eine leere Form. Auf diese Form zwei Buttons. Das ist alles.

Compilieren, starten. - Mittels Taskmanager Speicherverbrauch beobachten .... mal auf die Buttons klicken, andere Programme starten ....



Was ein Dreck ....

Gruss

EL

omata 29. Aug 2006 21:05

Re: Hat die MySQL oder die libmySQL.dll ein Memory Leak?
 
Hallo emsländer,

untersuch dein Problem doch mal mit MemProof.

Gruss
Thorsten


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:55 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 by Thomas Breitkreuz