Finalize-Methoden und Destruktoren
Für die meisten von der Anwendung erstellten Objekte führt der Garbage Collector von .NET Framework implizit alle für die Speicherverwaltung erforderlichen Aufgaben aus. Wenn Sie jedoch Objekte erstellen, die nicht verwaltete Ressourcen kapseln, müssen Sie die nicht verwalteten Ressourcen explizit freigeben, wenn diese nicht mehr von der Anwendung verwendet werden. Die häufigste Art einer nicht verwalteten Ressource ist ein Objekt, das den Wrapper einer Betriebssystemressource darstellt, z. B. eine Datei, ein Fenster oder eine Netzwerkverbindung. Der Garbage Collector kann die Lebensdauer eines Objekts verfolgen, das eine nicht verwaltete Ressource kapselt, verfügt jedoch über keine genauen Informationen zum Bereinigen dieser Ressource. Für diese Objekttypen bietet .NET Framework die Object.Finalize-Methode, mit der ein Objekt seine nicht verwalteten Ressourcen ordnungsgemäß bereinigen kann, wenn der Garbage Collector den vom Objekt verwendeten Arbeitsspeicher freigibt. In der Standardeinstellung erfüllt die Finalize-Methode keine Funktion. Wenn der Garbage Collector Bereinigungsoperationen für das Objekt ausführen soll, bevor der Speicher des Objekts freigegeben wird, müssen Sie die Finalize-Methode in der Klasse überschreiben.
Hinweis |
---|
Um die Finalize-Methode in C# zu implementieren, müssen Sie die Destruktorsyntax verwenden.In Version 2.0 von .NET Framework wird von Visual C++ für die Implementierung der Finalize-Methode eine eigene Syntax bereitgestellt, die unter Destructors and Finalizers in Visual C++ beschrieben ist.In Version 1.0 und 1.1 von .NET Framework wurde für die Finalize-Methode die Destruktorsyntax sowohl von Visual C++ als auch von C# verwendet. |
Der Garbage Collector verfolgt Objekte, die Finalize-Methoden besitzen, mithilfe der internen Struktur einer Finalisierungswarteschlange. Jedes Mal, wenn die Anwendung ein Objekt erstellt, das eine Finalize-Methode besitzt, platziert der Garbage Collector einen Eintrag, der auf das Objekt verweist, in der Finalisierungswarteschlange. Die Finalisierungswarteschlange enthält Einträge für alle Objekte im verwalteten Heap, für die Finalisierungscode aufgerufen werden muss, bevor der Garbage Collector deren Speicher freigeben kann.
Hinweis |
---|
Das Codebeispiel für die GC.KeepAlive-Methode veranschaulicht, wie durch agressive Garbage Collection die Ausführung eines Finalizers bewirkt werden kann, während ein Member des freigegebenen Objekts noch ausgeführt wird. Darüber hinaus wird veranschaulicht, wie die KeepAlive-Methode zu verwenden ist, um dies zu verhindern. |
Eine Finalize-Methode sollte keine Ausnahmen auslösen, da die Anwendung sie nicht behandeln kann und sie das Beenden der Anwendung verursachen können.
Das Implementieren von Finalize-Methoden oder Destruktoren kann die Leistung beeinträchtigen. Daher sollten Sie diese nur verwenden, wenn unbedingt erforderlich. Für das Freigeben des Speichers, der von Objekten mit Finalize-Methoden verwendet wird, sind mindestens zwei Garbage Collections erforderlich. Bei einer Garbage Collection wird der Speicher von Objekten ohne Finalizer freigegeben, auf die nicht zugegriffen werden kann. Währenddessen können keine Objekte freigegeben werden, die Finalizer besitzen. Stattdessen werden die Einträge dieser Objekte aus der Finalisierungswarteschlange entfernt und die Objekte in einer Liste mit Objekten platziert, die für die Finalisierung markiert sind. Die Einträge in dieser Liste zeigen auf Objekte im verwalteten Heap, für die der Finalisierungscode aufgerufen werden kann. Der Garbage Collector ruft die Finalize-Methoden für die Objekte in der Liste auf und entfernt dann die Einträge aus der Liste. Später ausgeführte Garbage Collections erkennen, dass für das finalisierte Objekt bereits eine Garbage Collection durchgeführt wurde, da auf dieses nicht mehr von Einträgen in der Liste mit Objekten verwiesen wird, die für die Finalisierung markiert sind. In dieser später ausgeführten Garbage Collection wird dann der Arbeitsspeicher des Objekts freigegeben.