title: Thread.FreeOnTerminate := True, memory leak and ghost running
body: <p>Years ago, I decided never to rely solely on setting a thread's <a href="http://docwiki.embarcadero.com/VCL/en/Classes.TThread.FreeOnTerminate" rel="nofollow noreferrer"><code>FreeOnTerminate</code></a> property to true to be sure of its destruction, because I discovered and reasoned two things at application's termination:</p>
  <ol>
  <li>it produces a memory leak, and</li>
  <li>after program's termination, the thread is still running somewhere below the keyboard of my notebook.</li>
  </ol>
  <p>I familiarized myself with a workaround, and it did not bother me all this time. Until tonight, when again someone (@MartinJames in this case) commented on <a href="https://stackoverflow.com/a/9025467/757830">my answer</a> in which I refer to some code that does not use <code>FreeOnTerminate</code> in combination with premature termination of the thread. I dove back in the RTL code and realized I may have made the wrong assumptions. But I am not quite sure about that either, hence this question.</p>
  <p>First, to reproduce the above mentioned statements, this illustrative code is used:</p>
  <pre><code>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.
  </code></pre>
  <p>Now (situation A), if you start the thread with a click on the form, and close the form right after the caption changed, there is a memory leak of 68 bytes. I assume this is because the thread is not freed. Secondly, the program terminates immediately, and the IDE is at that same moment back again in normal state. That in contrast to (situation B): when not making use of <code>FreeOnTerminate</code> and the last line of the above code is changed into <code>FThread.Free</code>, it takes (max.) 2 seconds from the disappearance of the program to the normal IDE state.</p>
  <p>The delay in situation B is explained by the fact that <code>FThread.Free</code> calls <code>FThread.WaitFor</code>, both which are executed in the context of the main thread. Further investigation of Classes.pas learned that the destruction of the thread due to <code>FreeOnTerminate</code> is done in the context of the worker thread. This lead to the following questions on situation A:</p>
  <ul>
  <li>Is there indeed a memory leak? And if so: is it important, could it be ignored? Because when an application terminates, doesn't Windows give back all its reserved resources?</li>
  <li>What happens with the thread? Does it indeed run further somewhere in memory until its work is done, or not? And: is it freed, despite the evidence of the memory leak?</li>
  </ul>
  <p>Disclaimer: For memory leak detection, I use <a href="https://github.com/NLDelphi/NLDUtils/blob/main/NLDMemLeak.pas" rel="nofollow noreferrer">this very simple unit</a> as first in the project file.</p>