2012-03-28 8 views
9

Ist ein finalisierbares Objekt mit GC.SuppressFinalize das gleiche wie ein normales nicht entklinkbares Objekt? Der Code scheint unten zu beweisen, sind sie anders behandelt, auf beiden .NET 2 und 4:GC.SuppressFinalize-Leistung im Vergleich zu nicht finalisierbarem Objekt

class Class1 { 

    public Class1() 
    { 
     GC.SuppressFinalize(this); 
    } 

    //~Class1() { } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Stopwatch sw = new Stopwatch(); 
     sw.Start(); 

     for (int i=0; i<100000000; i++) 
     { 
      new Class1(); 
     } 

     sw.Stop(); 
     Console.WriteLine(sw.ElapsedMilliseconds); 
    } 
} 

die Finalizerthread Hinzufügen, aber nicht irgendetwas anderes zu ändern, den Code verursacht weit weit mehr (12601 ms nehmen im Vergleich zu 889 ms).

Ich dachte, SuppressFinalize ein wenig in der Objekt-Header gesetzt, so dass der GC behandeln das Objekt das gleiche wie ein nicht finalisierbar Objekt, aber dies scheint nicht der Fall zu sein. So was ist los? Was unterscheidet ein nicht finalisierbares Objekt von einem finalisierbaren Objekt mit GC.SuppressFinalize?

+2

repro'd dies auf .net 4.5 beta too –

+0

Übrigens wiederholte ich den Test, aber stattdessen Zeit, wie lange es dauerte, um 'GC.Collect() zu tun; GC.WaitForPendingFinalizers(); GC.Collect(); 'nach all den' neuen '. Es gab keinen nennenswerten Unterschied zu vs ohne den (unterdrückten) Finalizer. – dlf

Antwort

7

Wie ich es verstehe, hat die CLR eine Warteschlange von Objekten, für die Finalisierung registriert wurde. Durch das Implementieren eines Finalizers werden Objekte des Typs in die Warteschlange gestellt. In dem Fall, in dem der Konstruktor SuppressFinalize aufruft, stelle ich mir vor, dass das Objekt tatsächlich in die Warteschlange gestellt wird, um sofort entfernt zu werden, was den Overhead erklären könnte.

+3

Ihre Phantasie ist genau :) –

+1

Das scheint sehr ineffizient. Ein nicht finalisierbares Objekt _should_ verhält sich genauso wie ein unterdrücktes finalisierbares Objekt. Es ist ziemlich überraschend, dass es anders ist – thecoop

+0

@thecoop: Vielleicht, aber jeder Typ, der einen Finalizer implementiert, muss zur Konstruktionszeit anders behandelt werden. Ich denke, Sie könnten eine Optimierung vornehmen, um zu überprüfen, ob die Finalisierung während des Konstruktors unterdrückt wird, aber ich glaube nicht, dass es sich lohnt. Im allgemeinen Fall geschieht die Unterdrückung einige Zeit nach der Konstruktion des Objekts. –

Verwandte Themen