Die Garbage Collection findet nicht statt, selbst wenn sie benötigt wird

Ich habe eine 64-Bit-WPF-Test-App erstellt. Während meine App ausgeführt wird und der Task-Manager geöffnet ist, verfolge ich die Speichernutzung meines Systems. Ich verwende 2 GB und habe 6 GB zur Verfügung.

In meiner App klicke ich auf die Schaltfläche Hinzufügen, um einer Liste ein neues 1-GB-Byte-Array hinzuzufügen. Ich sehe, dass meine Systemspeicherauslastung um 1 GB ansteigt. Ich klicke insgesamt 6 Mal auf Hinzufügen, um die 6 GB Speicher zu füllen, die mir zu Beginn zur Verfügung standen.

Ich klicke sechsmal auf die Schaltfläche Entfernen, um jedes Array aus der Liste zu entfernen. Die entfernten Bytearrays sollten von keinem anderen Objekt in meinem Steuerelement referenziert werden.

Wenn ich entferne, geht mein Gedächtnis nicht verloren. Aber das ist in Ordnung für mich, denn ich verstehe, dass GC nicht deterministisch ist und so weiter. Ich nehme an, dass der GC nach Bedarf sammelt.

Jetzt, da der Speicher voll ist, aber der GC bei Bedarf erfasst werden soll, füge ich ihn erneut hinzu. Mein PC rutscht in ein Disk Thrashing Coma hinein und aus ihm heraus. Warum hat der GC nicht gesammelt? Wenn das nicht der richtige Zeitpunkt wäre, wann dann?

Zur Überprüfung der geistigen Gesundheit habe ich einen Knopf, um die GC zu erzwingen. Wenn ich das drücke, bekomme ich schnell 6 GB zurück. Beweist das nicht, dass meine 6 Arrays nicht referenziert wurden und KÖNNTEN gesammelt worden sein, wenn der GC es gewusst hätte / gewollt hätte?

Ich habe viel gelesen, das besagt, dass ich GC.Collect () nicht aufrufen sollte, aber was kann ich sonst tun, wenn GC in dieser Situation nicht sammelt?

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

Antworten auf die Frage(3)

Ihre Antwort auf die Frage