Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Thread (Memory) wird nicht freigegeben (https://www.delphipraxis.net/74261-thread-memory-wird-nicht-freigegeben.html)

Peter Wolf 31. Jul 2006 15:09


Thread (Memory) wird nicht freigegeben
 
Hallo Gemeinde,

ich habe hier folgenden Thread:
Delphi-Quellcode:
unit Unit7;

interface

uses
  Classes, SysUtils, Windows;

type
  TTimerThread = class(TThread)
  private
    { Private-Deklarationen }
  protected
    Line: String;
    procedure DoAlive;
    procedure Execute; override;
  public
    constructor Create;
    destructor Destroy; override;
  end;

implementation
uses Unit5;

constructor TTimerThread.Create;
begin
  inherited Create(false);
  Priority:= tpHigher;
end;

destructor TTimerThread.Destroy;
begin
  Priority:= tpNormal;
  inherited;
end;

procedure TTimerThread.DoAlive;
begin
  DiagnosticForm.SendAll('Alive;'+TimeToStr(now));
end;

procedure TTimerThread.Execute;
var
  MyStart, MyEnd: Double;
begin
  while not Terminated do begin
    MyStart:= GetTickCount;
    Sleep(9000);
    MyEnd:= GetTickCount;
    while MyEnd - MyStart < 9000 do begin
      Sleep(10);
      MyEnd:= GetTickCount;
    end;
    DoAlive;
  end;
end;

end.
Bitte jetzt keine Posts, ob der Thread Sinn macht oder nicht.

Mir geht es um folgendes:
Beim Klicken auf den von mir erstellten Beenden-Button wird zuerst die DiagnosticForm beendet, in deren OnCloseQuery-Ereignis aufgerufen wird:
Delphi-Quellcode:
  DisconnectUser;
  idTcpServer.Active:= false;
  ledListening.Brush.Color:= clOff;
  CaseList.Free;
  if Assigned(MyTimerThread) then begin
    MyTimerThread.Terminate;
    MyTimerThread.WaitFor;
    MyTimerThread.Free;
    MyTimerThread:= nil;
  end;
  application.processMessages;
  canClose:= true;
MemCheck sagt mir, dass TTimerThread immer noch Speicher alloziiert.
Kann mir bitte jemand sagen, wo mein Fehler liegt.

Zitat:

MemCheck version 2.73

Exception: second release of block attempt, allocated at Module IdSchedulerOfThread.pas Routine @Idschedulerofthread@TIdSchedulerOfThread@NewYarn Line 246 Find error: 004C6593 - Already freed at (no debug info) Find error: 01FD8A34

Total leak: 68 bytes


*** MEMCHK: Blocks STILL allocated ***

Leak #0 Instance of TTimerThread
Size: 68
1 Occurence
call stack - 0 : Module Unit5.pas Routine @Unit5@TDiagnosticForm@Button2Click Line 792 Find error: 005DD02E
call stack - 1 : Routine @Controls@TControl@Click Find error: 00464A06
call stack - 2 : Routine @Menus@TMenuItem@Click Find error: 00475878
call stack - 3 : Routine @Controls@TWinControl@WndProc Find error: 004677B8
call stack - 4 : Routine @Controls@TWinControl@MainWndProc Find error: 00467433
call stack - 5 : Routine @Classes@StdWndProc Find error: 004270B6
call stack - 6 : (no debug info) Find error: 77D48730
call stack - 7 : (no debug info) Find error: 77D48812
call stack - 8 : (no debug info) Find error: 77D489C9
call stack - 9 : (no debug info) Find error: 77D496C3
call stack - 10 : Routine @Forms@TApplication@ProcessMessage Find error: 00483190
call stack - 11 : Module MITMonitor.dpr Routine initialization Line 21 Find error: 005F48FE
call stack - 12 : (no debug info) Find error: 7C816D4B
call stack - 13 : (no debug info) Find error: FFFFFFFC

*** MEMCHK: End of allocated blocks ***


*** MEMCHK: Chronological leak information ***

* Instance of TTimerThread (Leak #0) Size: 68

*** MEMCHK: End of chronological leak information ***


*** MEMCHK: Blocks written to after destruction ***

Bad blocks count: 0


*** MEMCHK: End of blocks written to after destruction ***


Grüße
Peter

Der_Unwissende 31. Jul 2006 16:40

Re: Thread (Memory) wird nicht freigegeben
 
Hi,
ich bin mir ehrlich gesagt nicht 100%ig sicher, aber kann es sein, dass FreeOnTerminate bei dir noch true ist? Denke das war bei Threads standardmässig so. Das führt dazu, dass wenn der Thread beendet wurde, der auch automatisch seine Methode free aufruft. Diese gibt natürlich dann den Speicher einfach frei, was wiederum zu Problemen führen kann. Wenn du hier einfach mal FreeOnTerminate false setzt und es testest (wie gesagt bin mir nicht ganz sicher!).

Eine andere Sache ist dann noch, dass es schwer zu sagen ist, wo du ein Memoryleak hast, wenn du nicht zeigst an welchen Stellen der Speicher belegt wird.
Du hast ja eine Variable, die eine Instanz dieses TThread speichert. Wenn du aber versehentlich eine Zuweisung vornimmst bevor die aktuelle Instanz frei gegeben wurde, hättest du (wenn FreeOnTerminate false ist) ebenfalls eine Mögliche Quelle für eine Leak.

Gruß Der Unwissende

Peter Wolf 1. Aug 2006 07:26

Re: Thread (Memory) wird nicht freigegeben
 
Hallo zusammen,

Problem ist gelöst.
Ich kann es zwar noch nicht nachvollziehen, aber ich habe nun das MyTimerThread.create etc. und das MyTimerThread.Terminate etc. an anderer Stelle aufgerufen, nun geht's.
Muss ich erst mal noch auf mich wirken lassen.


Danke und Grüße
Peter

Angel4585 1. Aug 2006 08:24

Re: Thread (Memory) wird nicht freigegeben
 
Ich persönlich würde im Create das FreeOnTerminate = True setzen und dan einfach nur Terminate aufrufen(Als des Free usw. weglassen)


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