Reputation: 148744
I'm having a trouble to understand what is the difference between WaitForFullGCComplete
and WaitForPendingFinalizers + collect
.
I already know that when a new object is created (which has a finalizer ) — A reference to that object is created in the finalization queue
.
Now - when a GC .collect
occurs and finds that the object should be collected , the reference from the finalization queue
moves to the f-reachable queue
.
These references in the queue are considered as a root
. Now — a special thread awakes from sleep at the f-reachable queue
and run each object's finalize
method .
Notice this is done AFTER the collect
phase. So only the next time we run GC.collect
the object would be truly gone.
If we want to wait until the f-reachable queue's
thread is done with all the finalize
methods - we should call : WaitForPendingFinalizers
.
And now if we want full collect , then we should run GC.collect again!.
If so - it seems that a full GC can be made by :
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
GC.WaitForPendingFinalizers();
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
So why would I need GC.WaitForFullGCComplete()
?
The docs says :
Returns the status of a registered notification for determining whether a full, blocking garbage collection by the common language runtime has completed.
Question
I don't understand : I already know when Gc has completed and it is at that point :
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
GC.WaitForPendingFinalizers();
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
//HERE <--
So when should I use that method as opposed to my code?
NB
(I saw it's usages here and here )
but their usage is not complete because - Not to mention that there is another method which should must be called in pairs :
From CLR via C# 4:
Note that you should always call the
WaitForFullGCApproach
andWaitForFullGCComplete
methods in pairs because the CLR handles them as pairs internally.
Upvotes: 8
Views: 4849
Reputation: 73502
Unless I misunderstood, both the usages in the link you've pointed out is wrong. As you quoted from CLR via C#, both WaitForFullGCApproach
and WaitForFullGCComplete
should be used in pairs.
WaitForFullGCComplete
is very different than Collect + WaitForPendingFinalizers
. Its usage is completely different.
Lets say you're writing a high performance, low latency server application which handles several thousands of requests per second. Obviously the server will allocate considerable amount of memory which can trigger a full gc(blocking!) which is a bad news for us.
Yes full gc will take a while to complete, till then you can't process the requests from clients (as your threads will be suspended). It isn't desirable for a high performance application to tolerate a full gc at peak hours.
In such case, if you want to redirect the further requests to some other server which can handle them, you'd use GC.RegisterForFullGCNotification
, GC.WaitForFullGCApproach
and GC.WaitForFullGCComplete
methods respectively.
WaitForFullGCApproach
will block till the GC decides to do a full gc, it is a notification for you to proactively redirect the requests or take some action.
Then WaitForFullGCComplete
will block till the full gc is completed. It is a notification for you to start processing the requests again.
GC.RegisterForFullGCNotification docs provides a good example and explains it better.
Upvotes: 9