年前、スレッドのFreeOnTerminate
プロパティをtrueに設定してアプリケーションの終了時に2つの事柄を発見して推論したので、Thread.FreeOnTerminate:= True、メモリリーク、ゴースト実行
- それはメモリリークを生成し、プログラムの終了後
- 、スレッドはまだどこかに私のノートパソコンのキーボードの下に実行されています。
私は回避策に慣れていましたが、今回はすべて気にしませんでした。今夜まで、もう一度誰かが(この場合は@MartinJames)my answerにコメントしました。ここでは、FreeOnTerminate
をスレッドの早すぎる終了と組み合わせて使用しないコードを参照しています。私はRTLコードに戻り、私が間違った前提を作ったかもしれないことに気付きました。しかし、私はそれについても、したがってこの疑問についてはあまりよく分かりません。
まず、上記の文を述べ再現するために、この例示的なコードが使用されます。
今unit Unit3;
interface
uses
Classes, Windows, Messages, Forms;
type
TMyThread = class(TThread)
FForm: TForm;
procedure Progress;
procedure Execute; override;
end;
TMainForm = class(TForm)
procedure FormClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
FThread: TMyThread;
end;
implementation
{$R *.dfm}
{ TMyThread }
procedure TMyThread.Execute;
begin
while not Terminated do
begin
Synchronize(Progress);
Sleep(2000);
end;
end;
procedure TMyThread.Progress;
begin
FForm.Caption := FForm.Caption + '.';
end;
{ TMainForm }
procedure TMainForm.FormClick(Sender: TObject);
begin
FThread := TMyThread.Create(True);
FThread.FForm := Self;
FThread.FreeOnTerminate := True;
FThread.Resume;
end;
procedure TMainForm.FormDestroy(Sender: TObject);
begin
FThread.Terminate;
end;
end.
(状況A)は、フォーム上のクリックでスレッドを開始し、右の後、フォームを閉じた場合キャプションが変更された、68バイトのメモリリークがあります。これは、スレッドが解放されていないためです。次に、プログラムは直ちに終了し、IDEは同じ瞬間に再び正常状態に戻ります。 (状況B)とは対照的に、FreeOnTerminate
を使用せず、上記のコードの最後の行をFThread.Free
に変更すると、プログラムが消滅してから通常のIDE状態に(最大)2秒かかります。
状況Bでの遅延は、FThread.Free
がFThread.WaitFor
を呼び出し、両方ともメインスレッドのコンテキストで実行されるという事実によって説明されます。 Classes.pasのさらなる調査では、FreeOnTerminate
によるスレッドの破棄はワーカースレッドのコンテキストで行われることが分かりました。これは、状況Aに関する次の質問につながります。
- 本当にメモリリークがありますか?もしそうなら、それは重要です、無視することができますか?アプリケーションが終了すると、Windowsはすべての予約済みリソースを返還しないので、
- スレッドはどうなりますか?その作業が完了するまで、それは実際にメモリのどこかでさらに実行されますか?そして:メモリリークの証拠にもかかわらず、それは解放されますか?
免責事項:メモリリーク検出では、私はthis very simple unitをプロジェクトファイルの最初に使用します。
あなたがすでに読んでいるかどうかわかりませんが、私は[Raymond Chen](http://blogs.msdn。com/b/oldnewthing)のようなものです。これを例に挙げてください(http://blogs.msdn.com/b/oldnewthing/archive/2012/01/05/10253268.aspx)または[2](http://blogs.msdn.com/ b/oldnewthing/archive/2007/05/02/2365433.aspx#2375204)。コメントやリンク先も見てください。 – EMBarbosa