Frage

  

Der Destruktor sollte nur freigeben nicht verwalteten Ressourcen, die Ihr Objekt hält an, und es sollte nicht andere Objekte verweisen. Wenn Sie nur Referenzen geschafft haben, brauchen Sie nicht zu (und sollte nicht) eine destructor implementieren. Sie wollen, dass diese nur für nicht verwalteten Ressourcen Handhabung. Da es einige Kosten ist eine destructor mit , sollten Sie diese auf Methoden nur implementieren, die wertvolle, nicht verwalteten Ressourcen verbrauchen.

     

- Top-Ten-Traps in C # für C ++ Programmierer

Der Artikel geht nicht in diesen in mehr Tiefe, aber welche Art von Kosten mit der Verwendung eines destructor in C # sind beteiligt?

Hinweis: Ich weiß um die GC und die Tatsache, die destructor nicht zuverlässig mal, dass alle zur Seite genannt wird, ist es etwas anderes

War es hilfreich?

Lösung

Jedes Objekt, das einen Finalizer hat (ich ziehe diesen Begriff über destructor, den Unterschied von C ++ Destruktoren zu betonen) an die Finalizerthread Warteschlange hinzugefügt. Dies ist eine Liste von Verweisen auf Objekte, die eine Finalizerthread hat, die aufgerufen werden muss, bevor sie entfernt werden.

Wenn das Objekt für die Garbage Collection ist, wird die GC findet, dass es in der Finalizer-Warteschlange ist und den Verweis auf die freachable (freachable) Warteschlange verschieben. Dies ist die Liste, die der Finalizerthread Hintergrund Faden durch die Finalizerthread Methode für jedes Objekt wiederum zu nennen geht.

Wenn der Finalizer des Objekts aufgerufen wurde, wird das Objekt nicht mehr in der Warteschlange Finalizerthread so ist es nur ein ganz normales verwaltete Objekt, dass der GC entfernen kann.

Das alles bedeutet, dass, wenn ein Objekt einen Finalizer hat, wird es mindestens eine Garbage Collection überleben, bevor sie entfernt werden kann. Das bedeutet in der Regel, dass das Objekt auf die nächste Generation Haufen bewegt werden, was tatsächlich beinhaltet die Daten im Speicher von einem Haufen zum anderem.

Andere Tipps

durch die umfangreichste Diskussion, die ich habe gesehen, wie das alles funktioniert von Joe Duffy gemacht wurde. Es hat mehr Details als Sie sich vorstellen können.

Im Anschluss daran, ich zusammen ein praktischer Ansatz Tag an einem Tag, dies zu tun -. weniger über die Kosten, sondern mehr über die Implementierung

Guffa und JaredPar decken die Details recht gut, so dass ich nur eine etwas esoterische Note auf Finalizers oder Destruktoren hinzufügen, um die Sprache C # Spezifikation sie leider nennt.

Eine Sache im Auge zu behalten ist, dass seit der Finalizerthread alle Finalizers in Folge ausgeführt wird, wird ein Deadlock in einem Finalizerthread verhindert alle verbleibenden (und Zukunft) Finalizers vom Laufen. Da diese Instanzen nicht gesammelt werden, bis ihre Finalizers vervollständigen ein Deadlock Finalizerthread wird auch ein Speicherleck verursachen.

Dieser Artikel behandelt das Problem im Detail. Es ist wirklich schwer in einfachem zusammenzufassen SO Beitrag: http: // msdn. microsoft.com/en-us/magazine/bb985010.aspx

Guffa hat recht gut, die Faktoren in den Finalizerthread Kosten aufsummiert. Es gab eine aktuelle Artikel über die Kosten der Finalizers in Java, die auch einen Einblick gibt.

Ein Teil der Kosten in .net kann durch Entfernen des Objekts aus der Finalizerthread Warteschlange mit GC.SuppressFinalize vermieden werden. Ich lief ein paar schnelle Tests in .net basiert auf Artikel und entsandte sie hier (obwohl der Fokus weit mehr auf der Java-Seite).


Im Folgenden finden Sie eine grafische Darstellung der Ergebnisse - es ist nicht wirklich die besten Etiketten ;-) hat. "Debug = true / false" bezieht sich auf die leere vs einfachen Finalizerthread:

~ConditionalFinalizer()  
{  
    if (DEBUG)  
    {  
        if (!resourceClosed)  
        {  
            Console.Error.WriteLine("Object not disposed");  
        }  
        resourceClosed = true;  
    }  
} 

"Suppress = true" bezieht sich auf, ob GC.SuppressFinalize im dipose Methode aufgerufen wurde.

Zusammenfassung

Für .net, von der Finalizerthread Warteschlange um das Objekt zu entfernen, indem GC.SuppressFinalize Aufruf ist die Hälfte der Kosten für die Warteschlange um das Objekt zu verlassen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top