How can I choose parameters for GC.RegisterForFullGCNotification?
If you want to receive GC notifications (for example, to transfer load between nodes during collection), then you can use the trio of methods, GC.RegisterForFullGCNotification, GC.WaitForFullGCApproach and GC.WaitForFullGCComplete - however, the parameters passed to GC.RegisterForFullGCNotification seem largely to be meaningless, and no real world guidance is given on how to choose suitable values. There are vague notes, like from here:
Use the following guidelines for specifying the maxGenerationThreshold and largeObjectHeapThreshold parameters:
The larger the threshold value, the further away in time the collection will likely occur and the sooner the notification will be raised.
A larger threshold value provides more opportunities for the runtime to check for an approaching collection. This increases the likelihood that you will be notified. However, you should not set the threshold too high because that results in a longer wait before the runtime induces the next collection.
When you induce a collection yourself upon notification using a high threshold value, more objects are reclaimed than would be reclaimed by the runtime's next collection.
The smaller the threshold value, the greater the likelihood that a collection will occur sooner and the notification will be raised later.
or from here
maxGenerationThreshold A number between 1 and 99 that specifies when the notification should be raised based on the objects promoted in generation 2.
largeObjectHeapThreshold A number between 1 and 99 that specifies when the notification should be raised based on the objects that are allocated in the large object heap.
If you specify a value that is too high, there is a high probability that you will receive a notification, but it could be too long a period to wait before the runtime causes a collection. If you induce a collection yourself, you may reclaim more objects than would be reclaimed if the runtime causes the collection.
If you specify a value that is too low, the runtime may cause the collection before you have had sufficient time to be notified.
However, that doesn't really help me choose sensible / correct numbers, except "not too high, not too low".
Currently, I'm just using one of the few provided examples, i.e.
// these are magic numbers; nobody really knows what they mean... GC.RegisterForFullGCNotification(10, 10);
but... it is very unclear whether 10,10 is a correct choice, an arbitrary choice, or how I should change this to reflect any particular usage scenario.
So: is there any correct way of choosing these numbers? Or is it just trial-and-error, based on whether I'm getting the events too early/late?
The best answer I could find on picking these parameters can be found in http://assets.red-gate.com/community/books/assets/Under_the_Hood_of_.NET_Management.pdf
You may be wondering about the magic constants in the call to RegisterForFullGC Notification. This method takes two parameters, maxGenerationThreshold and largeObjectHeapThreshold. Both parameters can be integers between 1 and 99. Larger values for these parameters will cause the notification to be raised earlier, and smaller values will cause the notification to be raised closer to when the event actually takes place.
The first parameter allows you to specify that you want to be notified based on the number of objects that have survived to Generation 2, and the second parameter specifies that you want to be notified based on the size of the Large Object Heap. However, neither parameter specifies an absolute value, so passing in 30 for the maxGenerationThreshold does not imply triggering a Notification when there are 30 objects in Generation 2; it simply means that you want to be notified earlier than if you had passed in a value of 10. Unless you are specifically more interested in one trigger over the other, you may want to pass in the same value for each parameter, as this will help ensure that you are notified at the same stage, regardless of the trigger.A larger value will give you more time to deal with memory pressure, but you just need to be careful not to set it too high. The higher you set the thresholds, the quicker you get notified but the longer you have to wait on the GC. Play with these parameters in your application to see what works best for your load and the types of objects consuming your memory.
So in answer, based on the above, it largely is trial and error however the two values you use for each parameter are likely to be the same.