In the course of a discussion in chat, I wrote this console application.
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();
}
}
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?
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.
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.
SustainedLowLatency . When entering and leaving either of these modes, it is recommended that you force a full GC with GC. Collect(2, GCCollectionMode. Forced) .
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With