locked
Finalizer RRS feed

  • Question

  • What is the core differnce betwenn destructor and Finalize()
    Wednesday, November 29, 2006 11:36 AM

Answers

  • There is no difference - the "~" is just syntactic sugar.
    Wednesday, November 29, 2006 11:47 AM
  • Actually, there are big differences. .NET does not offer destructors in the same sense as a C++ or Delphi destructor. .NET uses garbage collection, which means that for the most part, memory recapture and cleanup is a non-deterministic process - which is counter to the philosophy of non-GC environments such as the C++ runtime.

    A "Finalizer" in .NET is a special segment of code that the garbage collector can run (but doesnt by default, for good reason) once the object has been slated for decomission. By default, most .NET classes do not specify a finalizer - because simply having a finalizer defined means that it will take an extra garbage collection cycle to be fully reclaimed (while it waits its turn in the "finalization queue"). As the previous poster notes, the "~" is just how the C# compiler syntactically deals with Finalizer implementation.

    Finalizers are almost always implemented in conjunction with an IDisposable implementation - an interface that introduces the Dispose() method - which is somewhat reminiscent of old-school destructors, but also carries some "best practices when implementating" baggage. See the MSDN topic on this page for a complete discussion of the proper implementation of the Disposable pattern:

    http://msdn2.microsoft.com/en-us/library/fs2xkftw.aspx

    A few things to keep in mind:

    • The Garbage Collector will ultimately decide when to reclaim managed memory. Implementing IDisposable or ~Finalize() will not change this.
    • Dispose() is intended for releasing scarce and/or expensive Unmanaged resources (connections, files, GDI objects, etc). Simply nulling all references to a managed object is all that is required to release them - or for local stack variables within methods, once the function exits and the stack frame dies.
    • Once you implement the IDisposable interface, you are signaling to other developers that your class is a heavyweight and should be protected with using() blocks or try..finally blocks.
    • Declaring a ~ finalizer will cause your objects to always survive an extra GC cycle, because they are moved to the finalization queue instead of being immediately marked for reclamation.
    • Don't fight the GC unless you know you need to. It's actually pretty darn good at what it does. Memory allocation / deallocation is exceptionally efficient in .NET as compared to non-GC systems.

    HTH

     

    Thursday, November 30, 2006 3:31 AM

All replies

  • There is no difference - the "~" is just syntactic sugar.
    Wednesday, November 29, 2006 11:47 AM
  • Actually, there are big differences. .NET does not offer destructors in the same sense as a C++ or Delphi destructor. .NET uses garbage collection, which means that for the most part, memory recapture and cleanup is a non-deterministic process - which is counter to the philosophy of non-GC environments such as the C++ runtime.

    A "Finalizer" in .NET is a special segment of code that the garbage collector can run (but doesnt by default, for good reason) once the object has been slated for decomission. By default, most .NET classes do not specify a finalizer - because simply having a finalizer defined means that it will take an extra garbage collection cycle to be fully reclaimed (while it waits its turn in the "finalization queue"). As the previous poster notes, the "~" is just how the C# compiler syntactically deals with Finalizer implementation.

    Finalizers are almost always implemented in conjunction with an IDisposable implementation - an interface that introduces the Dispose() method - which is somewhat reminiscent of old-school destructors, but also carries some "best practices when implementating" baggage. See the MSDN topic on this page for a complete discussion of the proper implementation of the Disposable pattern:

    http://msdn2.microsoft.com/en-us/library/fs2xkftw.aspx

    A few things to keep in mind:

    • The Garbage Collector will ultimately decide when to reclaim managed memory. Implementing IDisposable or ~Finalize() will not change this.
    • Dispose() is intended for releasing scarce and/or expensive Unmanaged resources (connections, files, GDI objects, etc). Simply nulling all references to a managed object is all that is required to release them - or for local stack variables within methods, once the function exits and the stack frame dies.
    • Once you implement the IDisposable interface, you are signaling to other developers that your class is a heavyweight and should be protected with using() blocks or try..finally blocks.
    • Declaring a ~ finalizer will cause your objects to always survive an extra GC cycle, because they are moved to the finalization queue instead of being immediately marked for reclamation.
    • Don't fight the GC unless you know you need to. It's actually pretty darn good at what it does. Memory allocation / deallocation is exceptionally efficient in .NET as compared to non-GC systems.

    HTH

     

    Thursday, November 30, 2006 3:31 AM
  • I took the question to mean "What is the difference between C#'s destructor and the .Net Finalize() method?"

    To which the correct answer is "There is none".

    You have described the difference between the C++ destructor and a .Net Finalize(), which may well have been the OP's question!
    Thursday, November 30, 2006 9:47 AM
  •  ..."is a non-deterministic process"...

    You meant quasi-non-deterministic.

    Just like Newton's Theory of Gravity not Law of Gravity, of course unless it is 100%.

    Wednesday, May 6, 2020 11:08 PM