Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Memory Leak bei Russell Libby’s Pipe Componenten


Knulli - Mi 19.10.11 12:57
Titel: Memory Leak bei Russell Libby’s Pipe Componenten
Hi Leute,

ich versuche gerade ein MemoryLeak beim Schließen meiner Anwendung zu vermeiden, wenn ich die o.g. Pipe-Komponenten in meinem Programm verwende.

Kennt jemand die Komponenten und arbeitet damit und hat das gleiche Problem und konnte es beseitigen?

Hinweis: MemoryLeak tritt erst dann auf, wenn auch mindestens einmal eine Message vom PipeServer empfangen wurde.

mfg Knulli


Moderiert von user profile iconNarses: Topic aus Sonstiges (Delphi) verschoben am Mi 19.10.2011 um 15:48


BenBE - So 23.10.11 23:52

Übersetze deine Anwendung einmal mit Debug-Symbolen und zusätzlich FastMM mit der Einstellung "Full Debug Mode". Die Ausgabe der Memleaks ist dann um einiges umfangreicher. Anhand der dabei ausgegebenen Stack-Traces lässt sich der Pfad der Alloziierung rekonstruieren und somit auch, wo die Freigabe normalerweise hätte erfolgen müssen.


Knulli - Mo 24.10.11 09:04

Wo es herkommt, habe ich ermitteln können:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
procedure TPipeServer.AddWorkerThread(Pipe: HPIPE);
var  pstWorker:     TPipeThread;
     ppInfo:        PPipeInfo;
begin

  // Set worker thread
  pstWorker:=nil;

  // Create a new pipe info structure to manage the pipe
  ppInfo:=AllocPipeInfo(Pipe);

  // Resource protection
  try
     // Create the server worker thread
     pstWorker:=TPipeThread.Create(True, FHwnd, FBaseThread, ppInfo^.WriteQueue, FThreadCount, Pipe, ppInfo^.KillEvent);
     // Resource protection
     try
        // Set the OnTerminate handler
        pstWorker.OnTerminate:=RemoveWorkerThread;
     finally
        // Resume the thread
        pstWorker.Resume;
     end;
  except
     // Exception during thread create, remove the client record
     RemoveClient(Pipe);
     // Disconnect and close the pipe handle
     DisconnectAndClose(Pipe);
     // Free the worker thread object
     FreeAndNil(pstWorker);
  end;

end;


Der Thread wird erzeugt und die Referenz nur lokal gespeichert. Allerdings bin ich mir nicht sicher ob genau darin der Fehler des Entwicklers liegt, oder ob über irgend einen Trick der Therad am Ende der Applikation doch noch irgendwie freigegeben wird, und nur mein "ReportMemoryLeaksOnShutdown" etwas voreilig ist.

Knulli


Knulli - Mo 24.10.11 09:53

Habs mal in ein Beispielprojekt (Gruppe) gepackt, um das etwas anfassbarer zu machen...

Wenn Server gestartet wird und einfach wieder geschlossen wird, gibts kein MemoryLeak.

Empfängt der Server auch etwas vom Client, gibts beim Beenden des Servers die Meckermeldung von "ReportMemoryLeaksOnShutdown"

Knulli


BenBE - Mo 24.10.11 10:09

Versuch mal in der Methode TPipeServer.RemoveWorkerThread noch am Ende ein FreeAndNil(Sender); zu ergänzen. Das sollte normalerweise das Problem beheben.

Auch solltest du jegliche .Free;-Aufrufe durch FreeAndNil ersetzen, da es ansonsten zu Access Violations kommen kann.


bummi - Mo 24.10.11 10:49

Der Thread wird doch schon mit FreeOnTerminate:=True; erzeugt


axellang - Mo 24.10.11 18:37

Hi,

hier eine gefixte Version der pipes.pas die ich selbst verwende.

Axel