Wednesday, 26 October 2011

System.GC Methods and Properties

disclaimer: Apologies for the clinical nature of this post; any ideas on how to make the GC exciting or even interesting would be gratefully received.


There is a single property on the System.GC class
int MaxGeneration { get; }
This returns the maximum generation of objects the GC currently supports. See my post here for notes on generational GC.

System.GC implements the following methods (note, all are implemented as static methods):
void AddMemoryPressure(int bytesAllocated)
The GC.AddMemoryPressure method is used to inform the GC that a large unmanaged memory allocation has been performed. In normal circumstances, a managed object will use only managed memory, which will be kept track of by the GC. However, if a managed object allocates a large amount of unmanaged memory, AddMemoryPressure should be called to indicate to the GC that there is extra pressure on system memory. Doing so causes the GC to keep better track of the urgency of a collection. Keeping track of unmanaged memory pressure is particularly important when the object deallocates its unmanaged memory in its Finalize() method.
If applicable, AddMemoryPressure can be called once on each allocation of unmanaged memory.

void RemoveMemoryPressure(int bytesAllocated)
If a manual deallocation of unmanaged memory is performed, GC.RemoveMemoryPressure should be called to inform the GC of the reduction in the urgency of a collection.
This is the complementary method to AddMemoryPressure.

NB You should ensure that you remove exactly the same amount of pressure that you add. Failing to do so can adversely affect the performance of the system, particularly in applications that run for long periods of time.

void Collect()
This forces the GC to perform a collection. Memory for all unreachable objects in all generations will be reclaimed.

void Collect(int generation)
This overload forces the GC to collect memory, up to and including the specified generation.

void Collect(int generation, GCCollectionMode mode)
This overload forces the GC to collect memory, up to and including the specified generation.
    GCCollectionMode is one of:
    Default - currently equivalent to Forced
    Forced - Forces the garbage collection to occur immediately.
    Optimized - Allows the garbage collector to determine whether the current time is optimal to perform GC.

int CollectionCount(int generation)
This returns the count of collections that have occurred for the specified generation.

int GetGeneration(Object obj)
This returns the GC generation of the object.

int GetGeneration(WeakReference wo)
This overload returns the generation of the WeakReference specified (For the best description of how weak references work, see the section in this article Automatic Memory Management in the Microsoft .NET Framework, Part 2, and a code example).

int GetTotalMemory(bool forceFullCollection)
This returns the number of bytes currently believed to be allocated. The forceFullCollection parameter specifies whether GC should perform a collection before returning the approximate number of bytes allocated.

void KeepAlive(Object obj)
This is used to create a reference to an object in order to avoid it being collected by the GC. One reason for doing this is if the object is referenced in unmanaged code but not in managed; in normal circumstances this object would be available for collection by the GC, which would invalidate the unmanaged reference.
NB surprisingly, the call to KeepAlive should be performed at the point the object is no longer required to be kept alive.

void SuppressFinalize(Object obj)
This informs the GC that the Finalize method should not be called on obj. This should be used when all external resources have been disposed by obj. See my post here for notes on the finalizer.

void ReRegisterForFinalize(Object obj)
This informs the GC that it should call the Finalize method for obj, in spite of it having been passed to the SuppressFinalize method. See my post here for notes on the finalizer.

void WaitForPendingFinalizers()
This forces the current thread to wait until the finalization thread has finished calling the Finalize method of all finalizable objects. See my post here for notes on the finalizer.

void RegisterForFullGCNotification(int maxGenerationThreshold, int largeObjectHeapThreshold)
void CancelFullGCNotification()
GCNotificationStatus WaitForFullGCApproach()
GCNotificationStatus WaitForFullGCApproach(int millisecondsTimeout)
GCNotificationStatus WaitForFullGCComplete()
GCNotificationStatus WaitForFullGCComplete(int millisecondsTimeout)
These methods are used to register and unregister for notifications from the GC when it is about to perform a collection, and when it has completed a collection.
The example usage that Microsoft give here has the following pattern:
    Register for GC notification
    Start a thread dedicated to monitoring the GC, which will
        call WaitForFullGCApproach, and when a notification is raised
        call a static method in the class to signal a GC is approaching, in order to
        determine if a manual collection is required
    Cancel GC notification
GCNotificationStatus contains the following values:
    Succeeded
    Failed
    Canceled
    Timeout
    NotApplicable

Reference articles:
Microsoft documentation on System.GC
Microsoft article on Garbage Collection

No comments:

Post a Comment