Recolección de basura no ocurre incluso cuando es necesario

Hice una aplicación de prueba WPF de 64 bits. Con mi aplicación en ejecución y con el Administrador de tareas abierto, observo el uso de la memoria de mi sistema. Veo que estoy usando 2GB, y tengo 6GB disponibles.

En mi aplicación, hago clic en el botón Agregar para agregar una nueva matriz de 1 GB de bytes a una lista. Veo que el uso de la memoria de mi sistema aumenta en 1 GB. Hago clic en Agregar un total de 6 veces, llenando los 6 GB de memoria que tenía disponible cuando comencé.

Hago clic en un botón Eliminar 6 veces para eliminar cada matriz de la lista. Las matrices de bytes eliminadas no deben ser referenciadas por ningún otro objeto bajo mi control.

Cuando quito, no veo bajar mi memoria. Pero eso está bien conmigo, porque entiendo que GC no es determinista y todo eso. Me imagino que el GC se recogerá según sea necesario.

Así que ahora con la memoria llena, pero esperando que el GC se acumule cuando sea necesario, agrego nuevamente. Mi PC comienza a deslizarse dentro y fuera de un disco que golpea el coma. ¿Por qué no recogió el CG? Si ese no era el momento de hacerlo, ¿cuándo es?

Como una prueba de cordura, tengo un botón para forzar GC. Cuando presiono eso, rápidamente recupero 6GB. ¿No prueba eso que no se hizo referencia a mis 6 arreglos y PODRÍA haber sido recopilados si el GC hubiera sabido / querido?

He leído mucho que dice que no debería llamar a GC.Collect () pero si GC no recopila en esta situación, ¿qué más puedo hacer?

<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>

Respuestas a la pregunta(3)

Su respuesta a la pregunta