-1

I have a simple Account class. When I create an object referenced by "a". But after that I assign null to a. Further I have invoked GC.Collect(), whose job is to clear all abandoned object from heap memory. And since the object earlier referenced by a is not more referenced by any reference variable so it should be cleared and hence it's destructor should have been invoked. But surprisingly I am not getting the desired output.

  1. Is CLR performing some optimization ?
class Account
{
    int AccountNo;
    string Name;
    decimal Balance;
    public Account()
    {
        Console.WriteLine("account object created");
    }
    ~Account()
    {
        Console.WriteLine("account object destroyed");
    }
}

class ObjectOrientedExample
{
    static void Main()
    {
        Account a = new Account();
        a = null;
        GC.Collect();
    }
}
  • 1
    There's no such thing as a destructor in C#. There's a *finalizer*, and its syntax matches C++'s destructor syntax, but it's not a destructor. – madreflection Aug 31 '23 at 18:18
  • 2
    Furthermore, *"A correctly-written program cannot assume that finalizers will ever run at any point prior to program termination."* See: [Everybody thinks about garbage collection the wrong way](https://devblogs.microsoft.com/oldnewthing/20100809-00/?p=13203). – madreflection Aug 31 '23 at 18:18
  • Then what is the use of GC.Collect(), it is used to forcefully clear the unreferenced objects. – Prajval Gahine Aug 31 '23 at 18:20
  • 1
    Does this answer your question? [Is it possible to force C# finalizers be run in .NET Core on program exit?](https://stackoverflow.com/questions/66863320/is-it-possible-to-force-c-sharp-finalizers-be-run-in-net-core-on-program-exit) – gunr2171 Aug 31 '23 at 18:21
  • Where is object referenced by a is? In G0? – Prajval Gahine Aug 31 '23 at 18:28
  • 2
    Running finalizers at program exit was a feature of AppDomain, it was lost in .NETCore. You now have to provide enough time to give them a chance to run yourself, add `GC.WaitForPendingFinalizers();`. Target at least .net6.0 – Hans Passant Aug 31 '23 at 19:36
  • 1
    You, probably, are looking for `IDisposable` interface and `Dispose` method which is *guaranteed* to be executed when `a` is out of scope `using Account a = new Account();` – Dmitry Bychenko Aug 31 '23 at 19:42

1 Answers1

2

C# uses a finalizer, which is different from a destructor. Finalizers are not deterministic. You can't know for sure when they will run, even if the GC collects an instance of the object.

Mostly in C# you don't write finalizers at all. In fact, it's really rare. Instead, if you need deterministic disposal of a resource (other than memory!), you should implement the IDisposable pattern for the object. Adding a finalizer might be one part of this pattern, but it doesn't have to be, and in fact should only be done if you are managing a brand new kind of resources that doesn't already provide a finalizer somewhere in the inheritance tree.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
  • What does "collect them" means ? Does it mean that GC has recognised that this object is abandoned and ready for garbage collection ? Or the objects memory is released and made free ? – Prajval Gahine Sep 01 '23 at 02:41