title: Can delegates cause a memory leak? GC.TotalMemory(true) seems to indicate so
body: <p><strong>Code</strong></p>
  
  <pre><code>using System;
  internal static class Test
  {
      private static void Main()
      {
          try
          {
              Console.WriteLine("{0,10}: Start point", GC.GetTotalMemory(true));
              Action simpleDelegate = SimpleDelegate;
              Console.WriteLine("{0,10}: Simple delegate created", GC.GetTotalMemory(true));
              Action simpleCombinedDelegate = simpleDelegate + simpleDelegate + simpleDelegate;
              Console.WriteLine("{0,10}: Simple combined delegate created", GC.GetTotalMemory(true));
              byte[] bigManagedResource = new byte[100000000];
              Console.WriteLine("{0,10}: Big managed resource created", GC.GetTotalMemory(true));
              Action bigManagedResourceDelegate = bigManagedResource.BigManagedResourceDelegate;
              Console.WriteLine("{0,10}: Big managed resource delegate created", GC.GetTotalMemory(true));
              Action bigCombinedDelegate = simpleCombinedDelegate + bigManagedResourceDelegate;
              Console.WriteLine("{0,10}: Big combined delegate created", GC.GetTotalMemory(true));
              GC.KeepAlive(bigManagedResource);
              bigManagedResource = null;
              GC.KeepAlive(bigManagedResourceDelegate);
              bigManagedResourceDelegate = null;
              GC.KeepAlive(bigCombinedDelegate);
              bigCombinedDelegate = null;
              Console.WriteLine("{0,10}: Big managed resource, big managed resource delegate and big combined delegate removed, but memory not freed", GC.GetTotalMemory(true));
              GC.KeepAlive(simpleCombinedDelegate);
              simpleCombinedDelegate = null;
              Console.WriteLine("{0,10}: Simple combined delegate removed, memory freed, at last", GC.GetTotalMemory(true));
              GC.KeepAlive(simpleDelegate);
              simpleDelegate = null;
              Console.WriteLine("{0,10}: Simple delegate removed", GC.GetTotalMemory(true));
          }
          catch (Exception e)
          {
              Console.WriteLine(e);
          }
          Console.ReadKey(true);
      }
      private static void SimpleDelegate() { }
      private static void BigManagedResourceDelegate(this byte[] array) { }
  }
  </code></pre>
  
  <p><strong>Output</strong></p>
  
  <pre><code>GC.TotalMemory(true)
      105776: Start point
      191264: Simple delegate created
      191328: Simple combined delegate created
   100191344: Big managed resource created
   100191780: Big managed resource delegate created
   100191812: Big combined delegate created
   100191780: Big managed resource, big managed resource delegate and big combined delegate removed, but memory not freed
      191668: Simple combined delegate removed, memory freed, at last
      191636: Simple delegate removed
  </code></pre>