SoFunction
Updated on 2025-03-01

.Net  Detailed introduction to the garbage collection mechanism

Destructor

The destructor cannot have modifiers, such as public. No parameters are accepted.

The compiler automatically converts a destructor into an override version of the pair of methods, as follows.

class Test
{
  protected override void Finalize()
  {
    try {…}
    finally { (); }
  }
}

Garbage collector

The .NET garbage collector will ensure:

l  Every object will be destroyed, and its destructor will definitely be run. When a program is finished, all objects are destroyed.
l  Each object is destroyed only once.
l  Each object is destroyed only when it is not accessible (i.e. when there is no reference to the object).

How to work:

1)          It constructs a map containing all accessible objects. To do this, it will repeatedly follow the referenced fields in the object. The garbage collector will construct this map very carefully and ensure that the loop references do not recurse infinitely. No object in this map is considered unreachable.
2)           It checks whether any unreachable objects have a destructor that needs to be run (the process of running the destructor is called finalization). Any unreachable object that requires finalization will be placed in a special queue. This queue is called the freachable queue.
3)                                                                                                                               To do this, it moves the arrivable object down the heap, defragmenting the heap and freeing the memory located at the top of the heap. When the garbage collector moves an accessible object, the reference to that object is also updated.
4)                       It then allows other threads to resume execution
5)           It performs finalize operations on unreachable objects (located in the freachable queue) that require finalization in a separate thread.

As shown in the above summary, it can be seen that the existence of the destructor will cause the above process to perform 2 or 5 more steps. So consider using using block instead of generics. If a class used implements the Dispose method (Close method). It is best to call this method in finally (before calling the method, you need to check whether the distributed property of the object to be dispose is false, and only dispose is dispose if it is not true. This is also the reason why using is recommended. Using can easily constrain the scope of the variable to be destructed - that is, between a pair of braces). Or use the using block to enclose the code of this class. The type of the object placed in the using block must implement the IDisposable interface.

Standard Cleanup Mode

Finally, a standard cleaning mode code recommended for .NET is given, example code:

class MyClass : IDisposable
{
  private bool disposed = false;//Disposal status
  public void Dispose()//Public Dispose method (optional implementation of IDisposal interface)  {
    Dispose(true);
    (this);
  }

  ~MyClass()
  {
    Dispose(false);
  }

  protected virtual void Dispose(bool disposing)
  {
    if (!disposed)
    {
      if (disposing)
      {
        //Dispose the managed resources.
      }
      //Dispose the unmanaged resources.
    }
    disposed = true;
  }
}

In the above code, we call the Dispose method from the destructor, which ensures that the Dispose is executed. , and (this); is used to prevent the compiler from performing destruction on this object.

Thank you for reading, I hope it can help you. Thank you for your support for this site!