Coleta de lixo não está acontecendo mesmo quando necessário

Eu fiz um aplicativo de teste WPF de 64 bits. Com meu aplicativo em execução e com o Gerenciador de Tarefas aberto, vejo o uso da memória do sistema. Vejo que estou usando 2 GB e tenho 6 GB disponíveis.

No meu aplicativo, clico em um botão Adicionar para adicionar uma nova matriz de bytes de 1 GB a uma lista. Eu vejo o meu uso de memória do sistema aumenta em 1 GB. Eu clico em Adicionar um total de 6 vezes, preenchendo os 6 GB de memória que eu tinha disponível quando comecei.

Eu clico em um botão Remover 6 vezes para remover cada matriz da lista. Os arrays de bytes removidos não devem ser referenciados por nenhum outro objeto no meu controle.

Quando eu removo, não vejo minha memória cair. Mas tudo bem comigo, porque eu entendo que o GC é não determinista e tudo isso. Eu acho que o GC irá coletar quando necessário.

Portanto, agora com a memória parecendo cheia, mas esperando que o GC seja coletado quando necessário, eu adiciono novamente. Meu PC começa a entrar e sair de um coma de discos. Por que o GC não coletou? Se aquela não era a hora de fazê-lo, quando é?

Como verificação de integridade, tenho um botão para forçar o GC. Quando eu empurro isso, eu rapidamente recebo 6GB de volta. Isso não prova que meus 6 arrays não estavam sendo referenciados e que COULD teria sido coletado se o GC soubesse / quisesse?

Eu li muito que diz que eu não deveria chamar o GC.Collect (), mas se o GC não colecionar nesta situação, o que mais eu posso fazer?

<code>    private ObservableCollection<byte[]> memoryChunks = new ObservableCollection<byte[]>();
    public ObservableCollection<byte[]> 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 < 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 > 0)
        {
            memoryChunks.RemoveAt(0);
        }
    }

    private void GCButton_Click(object sender, RoutedEventArgs e)
    {
        GC.Collect();
        GC.WaitForPendingFinalizers();
    }
</code>

questionAnswers(3)

yourAnswerToTheQuestion