title: How do C# threads cause memory leaks when they already finished?
body: <p>Here's my code:</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Threading;
  namespace testt
  {
      class MainClass
      {
          public static List&lt;TestObject&gt; testjobs = new List&lt;TestObject&gt; ();
          public static void Main (string[] args)
          {
              Console.WriteLine ("Hello World!");
              addTask (); //put a breakpoint here
              Thread.Sleep (5000);
              deleteObj ();
              while (true) {
                  Console.WriteLine ("MAIN STILL EXISTS!");
                  Thread.Sleep (1500);
                  GC.Collect ();
              }
          }
          public static void addTask()
          {
              for (int i = 0; i &lt; 10; i++)
              {
                  testjobs.Add (new TestObject ());
                  testjobs [i].Start ();
              }
          }
  
          public static void deleteObj()
          {
              for(int i=0; i&lt;10;i++)
              {
                  testjobs [0].dispose ();
                  testjobs.RemoveAt (0);
              }
              Console.WriteLine (testjobs.Count);
          }
  
      }
  
      public class TestObject
      {
  
          private bool _isStopRequested;
          private Thread _thread;
          public void Start()
          {
              _thread = new Thread(ThreadRoutine);
              _thread.Start();
          }
  
          public void Stop()
          {
              _isStopRequested = true;
              if(!_thread.Join(5000))
              {
                  _thread.Abort();
              }
          }
  
          public void dispose(){
              this.Stop ();
              this._thread.Abort ();
              this._thread=null;
          }
  
  
          private void ThreadRoutine()
          {
              //while(!_isStopRequested) //THIS CAUSES THE MEMORY LEAK!!!
              {
              Thread.Sleep (1);
              }
              Console.WriteLine ("THREAD FINISHED");
          }
  
          ~TestObject(){
              Console.WriteLine ("===================TESTOBJECT DESTROYED!!===============");
          }
      }
  }
  </code></pre>
  
  <p>If you run it with the <code>//while(!_isStopRequested)</code> uncommented, the <code>TestObject</code> instances will not be destroyed, i.e their destructor methods will not be called. </p>
  
  <p>If you run it as is, then only 4-8 objects will be destroyed, not all 10 of them. </p>
  
  <p>Why does this happen when the threads have fully exited? I checked with the Xamarin debugger and the threads were definitely stopped. If you put a breakpoint in Xamarin at addTask(); then you can see that 10 threads </p>
  
  <p>My only explanation for this is that the thread somehow holds a reference back to their parent object TestObject instance even after they have finished. How can a thread hold a reference to their parent object when the thread has already finished? </p>
  
  <p>Also, if I change <code>Thread.Sleep(1)</code> to <code>Thread.Sleep(5000)</code>, the <code>TestObjects</code> also stop being collected. </p>
  
  <p>Also, as it is, only some TestObjects get collected whilst others don't. </p>
  
  <p>Why do these things happen? How can I ensure that ALL the TestObjects get garbage collected by the time the <code>deleteObj()</code> function returns? </p>
  
  <p>EDIT: I just tested the exact same code in Visual Studio (.NET) and all of the objects were garbage collected regardless of whether if that line was commented out or not. </p>
  
  <p>Therefore I now consider this issue to be a Mono-specific problem and there was no memory leak to begin with. </p>