Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Habe einen Speicherfresser, weis aber nicht wo :( (https://www.delphipraxis.net/142952-habe-einen-speicherfresser-weis-aber-nicht-wo.html)

Jackie1983 6. Nov 2009 15:42


Habe einen Speicherfresser, weis aber nicht wo :(
 
Servus,

vielleicht könnt ihr mir ja weiterhelfen. Wenn ich mein Programm übernacht laufen lasse, wird die Speicherauslastung immer mehr. Irgend wann leidet auch das System darunter.

Die Anwendung ist eine Client / Server Anwendung. Es wird als Test Daten vom Client zum Server gesendet. Als erstes wird ein Ping gesendet wenn ein Pong vom Server kommt werden alle Daten gesendet.

Wenn die Anwendung offline ist, ist soweit alles ok, nur wenn der Client verbunden ist, wird speicher verschlungen.
Also denke ich das der "Fehler" im read vom Client ist.

Hier ein wenig code.

Senden daten vom Client zum Server
Delphi-Quellcode:
procedure TThreadClient.Send(var Cmd: TCommandHandling; FreeCmd: Boolean);
var
  ping : TCommandHandling;
begin
  fSendCS.Enter;
  try
    if cmd <> nil then
      fJobsBuffer := fJobsBuffer + cmd.SendFrames;
  finally
    fSendCS.Leave;
  end;

  //Jobs zum server senden
  if (fSocketClient.Active) and (cmd <> nil) then
  begin
    if fJobsBuffer <> '' then
    begin
      //Erst mit einem Ping testen ob Verbindung besteht.
      LogMessage('OUT Ping');
      Ping := TCommandHandling.Create(SYS_PING);
      try
        fSocketClient.Socket.SendBuf(PChar(ping.SendFrames)^,Length(ping.SendFrames));
      finally
        FreeAndNil(ping);
      end;
    end;
  end;

  //Freigeben
  if FreeCmd then
    FreeAndNil(cmd);
end;
Daten vom Server lesen
Delphi-Quellcode:
procedure TThreadClient.OnClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  sBuffer,sJob : string;
  cmd,cmdRes : TCommandHandling;
  cmdSize : integer;
begin
  SetLength(sBuffer,Socket.ReceiveLength);
  Socket.ReceiveBuf(PChar(sBuffer)^,Length(sBuffer));

  FTempBuffer := FTempBuffer + sBuffer;
  SetLength(sBuffer, 0);

  while FTempBuffer <> '' do
  begin
    cmdSize := PCardinal(@FTempBuffer[1])^;
    if length(FTempBuffer) < cmdSize then break;

    sJob := copy(FTempBuffer,1,cmdSize);
    Delete(FTempBuffer,1,cmdSize);

    cmd := TCommandHandling.Create(CMDNone);
    cmd.SetFrames(sJob);
    case cmd.GetCmd of
      SYS_ALIVE : begin
        LogMessage('IN Alive');
        cmdRes := TCommandHandling.Create(SYS_ALIVE);
        try
          Socket.SendBuf(PChar(cmdRes.SendFrames)^,Length(cmdRes.SendFrames));
        finally
          FreeAndNil(cmdRes);
        end;
      end;
      SYS_PONG : begin
        fSendCS.Enter;
        try
          LogMessage('IN Pong');
          FPong := true;

          //Daten sende neu
          fSocketClient.Socket.SendBuf(PChar(fJobsBuffer)^,Length(fJobsBuffer));
          LogMessage('Job zum Server');
          LogMessage('OUT '+Dump(fJobsBuffer));
          fJobsBuffer := '';
          SetLength(fJobsBuffer, 0);
        finally
          fSendCS.Leave;
        end;
        //-----------------------------
      end;
    else if sJob <> '' then
      fJobCS.Enter;
      try
        fJobList.AddObject(sjob, socket);
      finally
        fJobCS.Leave;
      end;
      LogMessage('IN JOB: '+Dump(sJob));
    end; //case
    FreeAndNil(cmd);
  end; //while
end;
Ich bin der Meinung ich habe alles freigegeben.

DeddyH 6. Nov 2009 15:46

Re: Habe einen Speicherfresser, weis aber nicht wo :(
 
Zunächst einmal solltest Du try-finally-Blöcke verwenden, um die Freigabe in jedem Fall zu gewährleisten. Und in neueren Delphi-Versionen kannst Du zum Testen ReportMemoryLeaksOnShutdown auf true setzen, so dass Dir Speicherlecks beim Beenden des Programms gemeldet werden.

Jackie1983 6. Nov 2009 15:51

Re: Habe einen Speicherfresser, weis aber nicht wo :(
 
So wie es aussieht, habe ich ReportMemoryLeaksOnShutdown noch nicht.
Aber die lecks werden auch mit FastMM4 angezeigt, mein Programm hat keine.
Sobal ich die Anwendung schließe ist alles ok, nur im Betrieb wird irgend wo was verschlungen.

DeddyH 6. Nov 2009 15:54

Re: Habe einen Speicherfresser, weis aber nicht wo :(
 
Das kann ja eigentlich nur bedeuten, dass Du dynamisch irgendwelchen Speicher anforderst und erst spät wieder freigibst (fJobsBuffer würde ich z.B. einmal beobachten).

Jackie1983 6. Nov 2009 15:58

Re: Habe einen Speicherfresser, weis aber nicht wo :(
 
habe schon mal einen großen Speicherfresser gefunden. LogMessage speichert alles in einen String. Das heist auch jeden Befehl der gesendet wird, ist klar das der String immer größer wird :D
Ich werde das Programm einfach nochmal über nacht laufen lassen und mal schauen was bei rumkommt.

Jackie1983 6. Nov 2009 16:37

Re: Habe einen Speicherfresser, weis aber nicht wo :(
 
Darf den allgemein der Speicher größer werden. Das heist wenn eine Anwendung eine Woche läuft das die Speicherauslastung größer wird ist ok....

sirius 6. Nov 2009 16:40

Re: Habe einen Speicherfresser, weis aber nicht wo :(
 
ja, aber sollte sich asymptotisch dann doch einem Grenzwert nähern.

mjustin 6. Nov 2009 18:20

Re: Habe einen Speicherfresser, weis aber nicht wo :(
 
Bei Daten vom Server lesen fehlt noch try .. finally für die mit cmd := TCommandHandling.Create(CMDNone); erzeugte Instanz

Viele Grüße,


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