Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GC.Collect() not collecting immediately?

In the course of a discussion in chat, I wrote this console application.

Code:

using System;

class Program
{
    static void Main(string[] args)
    {
        CreateClass();
        Console.Write("Collecting... ");
        GC.Collect();
        Console.WriteLine("Done");
    }

    static void CreateClass()
    {
        SomeClass c = new SomeClass();
    }
}

class SomeClass
{
    ~SomeClass()
    {
        throw new Exception();
    }
}

Result:

Collecting... Done

Unhandled Exception: System.Exception: Exception of type 'System.Exception' was
thrown.
   at SomeClass.Finalize()

I would have expected the app to crash before Done was printed.

I don't care much about how to make it. My question is, why doesn't it?

like image 723
Kendall Frey Avatar asked Jul 05 '12 23:07

Kendall Frey


People also ask

When you request garbage collector to run it will start to run immediately?

It is not possible to run garbage collection immediately as we are programming in managed environment and only CLR decides when to run garbage collection.

What does GC collect () do?

It performs a blocking garbage collection of all generations. All objects, regardless of how long they have been in memory, are considered for collection; however, objects that are referenced in managed code are not collected. Use this method to force the system to try to reclaim the maximum amount of available memory.

When should you call GC collect?

SustainedLowLatency . When entering and leaving either of these modes, it is recommended that you force a full GC with GC. Collect(2, GCCollectionMode. Forced) .


Video Answer


1 Answers

Objects with finalizers cannot be collected within a single garbage collection procedure. Such objects are moved to f-reachable queue, and remain there until finalizers are called. Only after that they can be garbage-collected.

Following code is better, but you should not rely on it anyway:

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();

Also, throwing exceptions in finalizer seems too brutal for me, even for testing purposes.

Also, interesting side-effect of finalizers: an object with finalizer can still 'resurrect' itself (effectively prevent garbage collection of itself), if stores this reference in finalizer (assigns it to some static variable).

like image 146
max Avatar answered Oct 31 '22 18:10

max