Royi Namir
Royi Namir

Reputation: 148744

WaitForFullGCComplete vs (WaitForPendingFinalizers + collect)?

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 and WaitForFullGCComplete methods in pairs because the CLR handles them as pairs internally.

Upvotes: 8

Views: 4849

Answers (1)

Sriram Sakthivel
Sriram Sakthivel

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

Related Questions