title: Garbage Collection not happening even when needed
body: <p>I made a 64-bit WPF test app. With my app running and with Task Manager open, I watch my system memory usage.  I see I'm using 2GB, and I have 6GB available.</p>
  
  <p>In my app, I click an Add button to add a new 1GB byte array to a list.  I see my system memory usage increases by 1GB.  I click Add a total of 6 times, filling the 6GB of memory I had available when I started.</p>
  
  <p>I click a Remove button 6 times to remove each array from the list.  The removed byte arrays should not be referenced by any other object in my control.</p>
  
  <p>When I Remove, I don't see my memory go down.
  But that's OK with me, because I understand that GC is non-deterministic and all that.
  I figure the GC WILL collect as needed.</p>
  
  <p>So now with memory looking full, but expecting the GC to collect when needed, I Add again.
  My PC starts slipping in and out of a disk thrashing coma.
  Why didn't the GC collect?
  If that wasn't the time to do it, when is?</p>
  
  <p>As a sanity check, I have a button to force GC.  When I push that, I quickly get 6GB back.  Doesn't that prove my 6 arrays were not being referenced and COULD have been collected had the GC knew/wanted to?</p>
  
  <p>I've read a lot that says I shouldn't call GC.Collect() but if GC doesn't collect in this situation, what else can I do?</p>
  
  <pre><code>    private ObservableCollection&lt;byte[]&gt; memoryChunks = new ObservableCollection&lt;byte[]&gt;();
      public ObservableCollection&lt;byte[]&gt; MemoryChunks
      {
          get { return this.memoryChunks; }
      }
  
      private void AddButton_Click(object sender, RoutedEventArgs e)
      {
          // Create a 1 gig chunk of memory and add it to the collection.
          // It should not be garbage collected as long as it's in the collection.
  
          try
          {
              byte[] chunk = new byte[1024*1024*1024];
  
              // Looks like I need to populate memory otherwise it doesn't show up in task manager
              for (int i = 0; i &lt; chunk.Length; i++)
              {
                  chunk[i] = 100;
              }
  
              this.memoryChunks.Add(chunk);                
          }
          catch (Exception ex)
          {
              MessageBox.Show(string.Format("Could not create another chunk: {0}{1}", Environment.NewLine, ex.ToString()));
          }
      }
  
      private void RemoveButton_Click(object sender, RoutedEventArgs e)
      {
          // By removing the chunk from the collection, 
          // I except no object has a reference to it, 
          // so it should be garbage collectable.
  
          if (memoryChunks.Count &gt; 0)
          {
              memoryChunks.RemoveAt(0);
          }
      }
  
      private void GCButton_Click(object sender, RoutedEventArgs e)
      {
          GC.Collect();
          GC.WaitForPendingFinalizers();
      }
  </code></pre>