Meine zwei Cent für die GC.Collect-Methode in C #

Die Methode GC.Collect () ist bei .NET-Entwicklern seit langem beliebt. Allerdings wissen kaum wenige von uns, wie es tatsächlich funktioniert oder ob ein Anruf erforderlich ist.

Die CLR (Common Language Runtime) verwendet die Speicherbereinigung als Mechanismus zum Bereinigen der von Ihrer Anwendung verbrauchten Ressourcen. Beachten Sie, dass beim Erstellen von Objekten in .Net diese im verwalteten Heap gespeichert werden. Wenn Sie sie nicht mehr verwenden, müssen Sie sich keine Gedanken mehr über die Bereinigung machen - die Laufzeit würde dies für Sie tun.

Die CLR organisiert den verwalteten Heap in Generationen. Die drei Generationen, in denen der verwaltete Heap organisiert ist, sind: Generation 0, Generation 1 und Generation 2. Der GC ist in der Lage, den von verwalteten Objekten belegten Speicher zurückzugewinnen. Sie sollten jedoch bestimmte Richtlinien befolgen, um eine schnellere Speicherbereinigung zu ermöglichen und die Leistung Ihrer Anwendung zu verbessern.

Sollte ich die GC.Collect () -Methode verwenden?

Müssen Sie zuerst GC.Collect im Code Ihrer Anwendung aufrufen? Die Antwort lautet in den meisten Fällen nein. Lassen Sie mich Ihnen jetzt sagen, was diese Methode bewirkt und warum Sie diese Methode in den meisten Fällen nicht aufrufen sollten.

Wenn Sie die Methode GC.Collect () aufrufen, führt die Laufzeit einen Stapellauf durch, um die erreichbaren und nicht erreichbaren Objekte zu ermitteln. Außerdem wird der Hauptthread (und alle von ihm erstellten untergeordneten Threads) der Anwendung eingefroren. Mit anderen Worten, wenn die GC.Collect () -Methode aufgerufen wird, führt die Laufzeit eine blockierende Garbage Collection aller Generationen durch.

Ich würde es immer vorziehen, GC.Collect () nicht zu verwenden, es sei denn, es gibt einen bestimmten Grund, es zu verwenden. Ein GC besteht typischerweise aus den Markierungs- und Sweep-Phasen, gefolgt von einer Verdichtungsphase. Die Zeit, die die Laufzeit für die Durchführung eines GC benötigt, kann zu einem Engpass werden. Verwenden Sie sie daher nur sehr selten und wenn Sie es wirklich brauchen. Rico Mariani erklärt: "Erwägen Sie, GC.Collect () aufzurufen, wenn gerade ein einmaliges Ereignis aufgetreten ist und dieses Ereignis höchstwahrscheinlich dazu geführt hat, dass viele alte Objekte gestorben sind."

Verwenden der GC.Collect () -Methode

So können Sie die GC.Collect () -Methode in Ihrem Code aufrufen.

GC.Collect();

Beachten Sie, dass Sie auch Objekte sammeln können, die sich auf eine bestimmte Generation beziehen.

GC.Collect() - zum Sammeln von Objekten der Generationen 0, 1, 2

GC.Collect(0) - wird verwendet, um Objekte der Generation 0 zu sammeln

GC.Collect(1) - zum Sammeln von Objekten der Generationen 0 und

Sie können auch bestimmen, wie viel Speicher freigegeben wurde, indem Sie die Methode GC.Collect () aufrufen. Zu diesem Zweck können Sie die System.GC.GetTotalMemory () -Methode nutzen, wie im folgenden Codeausschnitt gezeigt.

//Write code to create some large objects here

Console.WriteLine("Total available memory before collection: {0:N0}", System.GC.GetTotalMemory(false));

System.GC.Collect();

Console.WriteLine("Total available memory collection: {0:N0}", System.GC.GetTotalMemory(true));

Mit der Methode GC.GetGeneration () kann die Generation ermittelt werden, zu der ein Objekt gehört. Siehe die unten angegebene Codeliste.

static void Main(string[] args)

       {

           List obj = new List() { "Joydip", "Steve" };

           Console.WriteLine(System.GC.GetGeneration(obj));

           System.GC.Collect();

           Console.WriteLine(System.GC.GetGeneration(obj));

           System.GC.Collect();

           Console.WriteLine(System.GC.GetGeneration(obj));

           Console.Read();

       }

Wenn Sie das obige Programm ausführen, wird Folgendes im Konsolenfenster gedruckt.

0

1

2

Wie Sie sehen können, befördert jeder Aufruf der GC.Collect () -Methode das Objekt "obj" zur nächsthöheren Generation. Dies liegt daran, dass das Objekt "obj" die Speicherbereinigung in jedem der beiden Fälle überlebt, dh es wird in keinem der beiden Aufrufe der Methode GC.Collect () zurückgefordert.

Mit der Methode GC.Collect () können Sie die Speicherbereinigung entweder für alle drei Generationen oder für eine bestimmte Generation erzwingen. Die GC.Collect () -Methode ist überladen - Sie können sie ohne Parameter aufrufen oder sogar die Generierungsnummer, die Sie sammeln möchten, an den Garbage Collector übergeben.

Beachten Sie, dass Objekte mit Finalisierern (und wenn die SuppressFinalize-Methode nicht aufgerufen wurde) beim Aufruf der GC.Collect () -Methode nicht erfasst werden. Vielmehr würden solche Objekte in die Finalisierungswarteschlange gestellt. Wenn Sie diese Objekte ebenfalls erfassen möchten, müssen Sie die Methode GC.WaitForPendingFinalizers () aufrufen, damit diese Objekte beim nächsten GC-Zyklus bereinigt werden. Im Wesentlichen erfordert das Zurückfordern des Speichers, der von Objekten belegt wird, für die Finalizer implementiert sind, zwei Durchgänge, da solche Objekte in die Finalisierungswarteschlange gestellt werden und nicht im ersten Durchgang zurückgefordert werden, wenn der Garbage Collector ausgeführt wird.