Recipe 14.17. Fine-Tuning Garbage Collection


Problem

The .NET garbage-collection process is something of a mystery, a black box that has a mind of its own. Does a programmer have any control over the disposal process?

Solution

The System.GC object exposes several methods that let you "help" the garbage-collection process, either for a specific object or for the entire garbage system.

When you finish using an object by setting it to Nothing or by letting it otherwise become unused (go out of scope), it is added to the garbage-collection system for eventual finalization and disposal. Finalization occurs when the object's Finalize() method is called. Disposal occurs when the memory allocated to the object is finally reclaimed and made available for use by other managed (or even unmanaged) uses.

Garbage collection occurs in waves, or generations. When an object first enters the system, it appears in Generation 0 (zero). If, after a while, the object has not yet been finalized or disposed of, it is moved to the next generation, Generation 1. Not all platforms support this system of aging. Use the System.GC.MaxGeneration property to determine the generation of the longest-lived object. This property always returns zero on platforms that do not use aging.

Discussion

You can use the following members of System.GC to help manage the garbage-collection system in memory-critical applications:


AddMemoryPressure() and RemoveMemoryPressure()

The garbage-collection system concerns itself only with managed memorymemory allocated through .NET features. Unmanaged memory does not go through the collection process. However, the collection process does take the amount of available memory, both managed and unmanaged, into account when determining how quickly to free resources. The AddMemoryPressure( ) method accepts a byte count argument and tells the garbage collector, "Act as if this amount of unmanaged memory has actually been allocated." Depending on the size of the pressure, the collection process will behave differently due to the perceived changes in available memory.

You must later reverse the pressure allocation with the RemoveMemoryPressure( ) method, using the same byte count supplied with the original pressure request. You can have multiple pressure requests active at once.


Collect( )

This method forces the immediate collection (finalization and disposal) of garbage. By default, this method collects garbage in all generations. You can also pass it a generation number, and it will collect garbage only between Generation 0 and the generation number of the argument.


CollectionCount( )

This method returns a count of the number of times garbage has been collected for a specific generation number. The generation number is passed as an argument.


GetGeneration( )

If you have access to a reference object that has already entered the garbagecollection system, passing it as an argument to GetGeneration( ) returns the generation number in which that object appears.


GetTotalMemory( )

This method returns an estimate of the total allocated managed memory. It accepts a Boolean argument that, if true, allows garbage collection to occur before the estimate is calculated.


KeepAlive( )

Normally, when an object goes out of scope, you don't care when the garbagecollection process destroys it. However, if you allocate some managed memory that you will share with or pass to an external or unmanaged process (such as an ActiveX DLL function), and that process will use the memory beyond your local use of it, the garbage collector should delay processing of the object until it is truly no longer in use. The KeepAlive( ) method helps you force such a delay.

To use KeepAlive( ), you pass it a reference to the object to retain, and you call this method when you no longer wish to retain it. That is, the call to KeepAlive( ) says, "Keep the object alive, but only until this point; after this call, it can go to garbage collection." For this reason, calls to GC.KeepAlive( ) generally appear near the end of a method or block of code.


SuppressFinalize( ) and ReRegisterForFinalize( )

Passing an object reference to SuppressFinalize( ) tells the garbage collector, "Don't call this object's Finalize( ) method before disposing of the object." This method is most commonly used with objects that implement the System.IDisposable interface. If you clean up all allocated resources during the call to Dispose( ), such that there is nothing more for the Finalize( ) method to do, adding a call to SuppressFinalize( ) disables the unneeded call to Finalize( ).

Visual Studio normally adds some template code to your class when you declare it using Implements IDisposable. This template code includes a call to SuppressFinalize( ). You may or may not wish to retain this call, depending on your needs.

If you use the SuppressFinalize( ) method but later find that you need to reenable the finalization process for an object, call the ReRegisterForFinalize( ) method.


WaitForPendingFinalizers( )

This method suspends execution of the application until all relevant objects in the garbage collector have had their Finalize( ) methods called.

Most of these methods are designed for applications with advanced memory-allocation and processing needs. In most ordinary applications, only the KeepAlive( ) and SuppressFinalize( ) methods will find common use.




Visual Basic 2005 Cookbook(c) Solutions for VB 2005 Programmers
Visual Basic 2005 Cookbook: Solutions for VB 2005 Programmers (Cookbooks (OReilly))
ISBN: 0596101775
EAN: 2147483647
Year: 2006
Pages: 400

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net