Understanding garbage collection in .NET

前端 未结 2 1655
[愿得一人]
[愿得一人] 2020-11-21 04:58

Consider the below code:

public class Class1
{
    public static int c;
    ~Class1()
    {
        c++;
    }
}

public class Class2
{
    public static void         


        
2条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2020-11-21 05:24

    [ Just wanted to add further on the Internals of Finalization process ]

    So, you create an object and when the object is collected, the object's Finalize method should be called. But there is more to finalization than this very simple assumption.

    SHORT CONCEPTS::

    1. Objects NOT implementing Finalize methods, there Memory is reclaimed immediately,unless of course, they are not reacheable by
      application code anymore

    2. Objects implementing Finalize Method, The Concept/Implementation of Application Roots, Finalization Queue, Freacheable Queue comes before they can be reclaimed.

    3. Any object is considered garbage if it is NOT reacheable by Application Code

    Assume:: Classes/Objects A, B, D, G, H do NOT implement Finalize Method and C, E, F, I, J implement Finalize Method.

    When an application creates a new object, the new operator allocates the memory from the heap. If the object's type contains a Finalize method, then a pointer to the object is placed on the finalization queue.

    therefore pointers to objects C, E, F, I, J gets added to finalization queue.

    The finalization queue is an internal data structure controlled by the garbage collector. Each entry in the queue points to an object that should have its Finalize method called before the object's memory can be reclaimed. Figure below shows a heap containing several objects. Some of these objects are reachable from the application's roots, and some are not. When objects C, E, F, I, and J were created, the .Net framework detects that these objects have Finalize methods and pointers to these objects are added to the finalization queue.

    enter image description here

    When a GC occurs(1st Collection), objects B, E, G, H, I, and J are determined to be garbage. Because A,C,D,F are still reacheable by Application Code depicted through arrows from yellow Box above.

    The garbage collector scans the finalization queue looking for pointers to these objects. When a pointer is found, the pointer is removed from the finalization queue and appended to the freachable queue ("F-reachable").

    The freachable queue is another internal data structure controlled by the garbage collector. Each pointer in the freachable queue identifies an object that is ready to have its Finalize method called.

    After the collection(1st Collection), the managed heap looks something similar to figure below. Explanation given below::
    1.) The memory occupied by objects B, G, and H has been reclaimed immediately because these objects did not have a finalize method that needed to be called.

    2.) However, the memory occupied by objects E, I, and J could not be reclaimed because their Finalize method has not been called yet. Calling the Finalize method is done by freacheable queue.

    3.) A,C,D,F are still reacheable by Application Code depicted through arrows from yellow Box above, So they will NOT be collected in any case

    enter image description here

    There is a special runtime thread dedicated to calling Finalize methods. When the freachable queue is empty (which is usually the case), this thread sleeps. But when entries appear, this thread wakes, removes each entry from the queue, and calls each object's Finalize method. The garbage collector compacts the reclaimable memory and the special runtime thread empties the freachable queue, executing each object's Finalize method. So here finally is when your Finalize method gets executed

    The next time the garbage collector is invoked(2nd Collection), it sees that the finalized objects are truly garbage, since the application's roots don't point to it and the freachable queue no longer points to it(it's EMPTY too), Therefore the memory for the objects (E, I, J) are simply reclaimed from Heap.See figure below and compare it with figure just above

    enter image description here

    The important thing to understand here is that two GCs are required to reclaim memory used by objects that require finalization. In reality, more than two collections cab be even required since these objects may get promoted to an older generation

    NOTE:: The freachable queue is considered to be a root just like global and static variables are roots. Therefore, if an object is on the freachable queue, then the object is reachable and is not garbage.

    As a last note, remember that debugging application is one thing, Garbage Collection is another thing and works differently. So far you can't FEEL garbage collection just by debugging applications, further if you wish to investigate Memory get started here.

提交回复
热议问题