Garbage Collection nie działa nawet wtedy, gdy jest to potrzebne

Zrobiłem 64-bitową aplikację testową WPF. Dzięki uruchomionej aplikacji i otwartemu Menedżerowi zadań obserwuję zużycie pamięci systemowej. Widzę, że używam 2 GB, a mam 6 GB.

W mojej aplikacji klikam przycisk Dodaj, aby dodać nową tablicę bajtów 1 GB do listy. Widzę, że zużycie pamięci systemowej wzrasta o 1 GB. Klikam Dodaj łącznie 6 razy, wypełniając 6 GB pamięci, którą miałem dostępną, gdy zacząłem.

Klikam przycisk Usuń 6 razy, aby usunąć każdą tablicę z listy. Do usuniętych tablic bajtów nie powinny odwoływać się żadne inne obiekty znajdujące się pod moją kontrolą.

Kiedy usuwam, nie widzę, że moja pamięć spada. Ale to jest w porządku dla mnie, ponieważ rozumiem, że GC jest niedeterministyczne i to wszystko. Myślę, że GC BĘDZIE zbierać w razie potrzeby.

Więc teraz, gdy pamięć wygląda na pełną, ale oczekuję, że GC zbierze się w razie potrzeby, ponownie dodam. Mój komputer zaczyna się wsuwać i wysypywać ze śpiączki na dysku. Dlaczego GC nie zebrał? Jeśli to nie był czas, aby to zrobić, kiedy to jest?

Jako test poprawności mam przycisk do wymuszenia GC. Kiedy to pcham, szybko odzyskuję 6 GB. Czy to nie dowodzi, że moje 6 tablic nie było przywoływane i MOGŁO zostać zebrane, gdyby GC wiedział / chciał?

Czytałem dużo, że nie powinienem dzwonić do GC.Collect (), ale jeśli GC nie zbiera się w tej sytuacji, co jeszcze mogę zrobić?

<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