GC.Collect () und Finalize
Ok, es ist bekannt, dass GC implizit fordert Finalize
Methoden auf Objekte, wenn es identifiziert das Objekt als Müll. Aber was passiert, wenn ich eine GC.Collect()
? Sind die Finalizer noch ausgeführt werden? Eine dumme Frage vielleicht, aber jemand fragte mich und ich antwortete "ja" und dann dachte ich: "War, richtig voll?"
InformationsquelleAutor der Frage Sandeep | 2012-12-19
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nein, Nein, Nein. Das ist nicht bekannt da, um wissen eine Erklärung muss wahr. Diese Aussage ist false. Die Speicherbereinigung nicht ausgeführt Finalizer, wie es Spurenob es sich selbst ausführt, oder ob man
Collect
. Der finalizer-thread läuft Finalizer nach der tracing-Sammler gefunden hat, der Müll und das passiert asynchron mit Bezug auf einen AufrufCollect
. (Wenn es geschieht, an alle, die es möglicherweise nicht, wie eine andere Antwort Punkte aus.) Das heißt, verlassen Sie sich nicht auf die finalizer-thread ausführen, bevor Sie die Kontrolle zurück, ausCollect
.Hier ist eine grob vereinfachte Skizze, wie es funktioniert:
Wie gesagt, das ist stark vereinfacht; die genauen details, wie die finalizer-Warteschlange funktioniert sind ein bisschen mehr kompliziert als das. Aber es wird genug von der Idee, über. Das praktische Ergebnis ist hier, dass Sie können nicht davon ausgehen, dass der Aufruf
Collect
läuft auch Finalizerweil es für Sie nicht. Lassen Sie mich wiederholen, dass man mehr Zeit: die Ablaufverfolgung Teil der garbage collector macht nicht laufen FinalizerundCollect
läuft nur die tracing-Teil der collection-Mechanismus.Nennen das treffend benannte
WaitForPendingFinalizers
nach dem AufrufCollect
wenn Sie möchten, um zu garantieren, dass alle Finalizer ausgeführt haben. Das pausiert im aktuellen thread bis der finalizer-thread herum zu dem leeren der Warteschlange. Und wenn Sie wollen,, um sicherzustellen, dass diejenigen, die abgeschlossen haben Objekte, die Ihre Speicher zurückgefordert wird, dann sind Sie gehen zu müssen, rufen SieCollect
eine zweiten Zeit.Und natürlich, es geht ohne zu sagen, dass Sie sollten nur tun dies für debugging-und Testzwecke. Nie tun, diesen Unsinn in der Produktion code, ohne eine wirklich wirklich gutem Grund.
InformationsquelleAutor der Antwort Eric Lippert
Eigentlich ist die Antwort "Es kommt darauf an". Tatsächlich gibt es einen eigenen thread, der ausgeführt wird, alle Finalizer. Das bedeutet, dass der Aufruf
GC.Collect
nur ausgelöst, das den Prozess und die Ausführung aller Finalizer aufgerufen werden würde, asynchron.Wenn Sie möchten, zu warten, bis alle Finalizer aufgerufen werden würde, können Sie folgenden trick:
InformationsquelleAutor der Antwort Sergey Teplyakov
Ja, aber nicht sofort. Dieser Auszug ist aus Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework (MSDN-Magazin) (*)
(*) Von November 2000, also könnten sich die Dinge geändert haben, seit.
InformationsquelleAutor der Antwort stuartd
Wenn der Müll gesammelt (ob in Reaktion auf Arbeitsspeicher oder
GC.Collect()
), die Objekte erfordern Abschluss werden Abschluss-Warteschlange.Es sei denn, Sie rufen
GC.WaitForPendingFinalizers()
der Finalizer kann weiter im hintergrund ausführen, lange nachdem die garbage collection abgeschlossen ist.BTW, es gibt keine Garantie Finalizer aufgerufen werden an alle. Von MSDN...
InformationsquelleAutor der Antwort Branko Dimitrijevic
Paar mehr Punkte Wert sind, hier anzugeben.
Finalizer ist der Letzte Punkt wo .net-Objekten kann die Freigabe nicht verwalteter Ressourcen.
Finalizer ausgeführt werden sollen, nur, wenn Sie nicht entsorgen Sie Ihre Instanzen korrekt. Idealerweise Finalizer sollte nie ausgeführt werden, in vielen Fällen. Da die ordnungsgemäße Entsorgung der Umsetzung sollte unterdrücken der Fertigstellung.
Hier ist ein Beispiel für die korrekte Umsetzung IDispoable.
Wenn Sie die Dispose-Methode eines Einweg-Objekte, sollte es deaktivieren Sie alle Verweise und Unterdrückung der Abschluss. Wenn es einem nicht so guten Entwickler, vergessen, rufen Sie die Dispose-Methode, Finalizer ist der Lebensretter.
InformationsquelleAutor der Antwort CharithJ