Sie sollten nur einen Finalizer hinzufügen, wenn Sie absolut haben, um einige Bereinigung an einem bestimmten Punkt auszuführen, ob es explizit durchgeführt wird oder nicht. In solchen Fällen sollten Sie immer eine explizite Möglichkeit haben, die Bereinigung trotzdem zeitnah durchzuführen, und dies sollte die Finalisierung sowieso unterdrücken, damit "gute" Clients keine Leistungseinbußen sehen.
Sie würden normalerweise nur einen Finalizer benötigen, wenn Sie einen direkten Griff zu nicht verwalteten Ressourcen haben - wenn Sie nur einen Verweis auf andere Klasse, die auf der Ressource einen Griff (zB FileStream
), dann sollten Sie es auf die verlassen andere Klasse, um einen Finalizer zu haben.
Mit dem Aufkommen von SafeHandle
in .NET 2.0, Situationen, in denen es Ihre eigene Finalizerthread schreiben sind very rare indeed wert ist.
Die Leistungseinbußen der Finalizer sind, dass sie Ihre Objekte länger leben lassen, als sie brauchen: Im ersten GC-Zyklus, in dem sie sonst für die Sammlung in Frage kommen, werden sie in die Finalizer-Warteschlange aufgenommen - und sind dort angekommen die nächste Generation genau wie jedes andere Objekt, das einen GC-Zyklus überlebt. Der Finalizer wird dann in einem anderen Thread (irgendwann) laufen und nur dann werden sie berechtigt sein, wirklich gesammelt werden. Anstatt also in der ersten Gen1-Sammlung gesammelt zu werden, leben sie weiter, bis zur nächsten Sammlung, die wesentlich später sein kann.
Ja, schade, dass selbst die Fx4-Version dieses Links SafeHandle nicht erwähnt. –
Eine größere Leistungseinbuße besteht darin, dass alle Objekte , die mit einem finalisierbaren Objekt auf referenziert werden, für eine andere Generation nicht erfassbar sind, ebenso wie Objekte, auf die von diesen verwiesen wird, oder Objekte, auf die sie verweisen usw. Wenn ein Objekt direkt oder indirekt referenziert Objekte, die während der Finalisierung nicht benötigt werden, sollte das Objekt keinen Finalizer haben. Stattdessen sollten die Dinge, die tatsächlich für die Finalisierung benötigt werden, in ihrer eigenen finalisierbaren Klasse eingekapselt werden, und das größere Objekt sollte einen Verweis darauf enthalten. – supercat