Best Practices for Managing Memory                                                
•        The GC.Collect() method may be called directly within *.exe applications to help keep the heap clean
and tidy.
•        Commonly done after lengthy and time consuming operations (I/O operations, time-intensive
calculations, etc).
•        Doing so allows you to piggy back the time spent GC-ing on an already lengthy operation (rather than
at random moments during the execution of your program).
•        However, never interact with the GC from within a *.dll assembly.  GC interactions should be the job
of the main application.
•        Also, never interact with the GC from server side applications (COM+ apps, ASP.NET apps, web
services).
•        Server side apps are hosted by surrogates which are highly optimized for the .NET GC.  
•        After calling GC.Collect(), your very next line of code should be GC.WaitForPendingFinalizers().
•        Finalizers are executed on a secondary thread.
•        If an object has a custom finalizer implementation, you will want to let that thread finish its activity
before continuing.
•        If you don’t do so, there is a risk you might use an object not yet finalized!
// C# code (VB 2005 folks just remove semi-colons)
SomeMethodDoingLengthyTask();
GC.Collect();
GC.WaitForPendingFinalizers();

•        Avoid allocating extreamly large objects (> 85,000 bytes).
•        This is due to the fact that very large objects are allocated to a separate heap which is not compacted
after sweeps (it would take too long).
•        Thus, the large object heap can become fragmented, resulting in a loss of heap space for allocation (even
if there is indeed enough collective space).
•        If you determine you have extreamly large objects, attempt to break them into 2 or more smaller
instances.
•        When making use of local reference types, there is no compelling reason to set the refence to null (C#)
or Nothing (VB) before exiting scope.
•        The compilers will be able to determine if the object is not used beyond the method scope and optimize
accordenly.
•        However, when using a reference type within a loop, setting the reference to null / Nothing is useful.
•        For example, only 10 or 50 cycles need the object reference.
•        In these cases, the compilers cannot figure out when the object is not needed, and therefore cannot
optimize the process.
•        Setting the variable to null / Nothing is a helpful hit to the GC to kill the object a.s.a.p.

•        Always explicitly unsubscribe from events when you no longer need to receive the event.
•        The reason has to do with the fact that the underlying delegate is holding a reference to the delegate
target.
•        Thus, the target object cannot be GC-ed until the delegate is GC-ed.
•        In most cases, the will result in the target object being held in memory for far longer than needed.
•        C# developers can subscribe / unsubscribe from an event using the += / -= operators.
•        VB 2005 developers can use the AddHandler / RemoveHandler statements.
// C#
MyEventObject o = new MyEventObject();
o.SomeEvent += new RelatedDelegate(methodToCall);

// Use object here...

// Explicitly disconnect and set to null.
o.SomeEvent -= new RelatedDelegate(methodToCall);
o = null;

' VB 2005
Dim o As New MyEventObject()
AddHandler o.SomeEvent, AddressOf methodToCall

' Use object here...

' Explicitly disconnect and set to Nothing.
RemoveHandler o.SomeEvent, AddressOf methodToCall
o = Nothing
Managing Memory
Table of Contents
Copyright (c) 2008.  Intertech, Inc. All Rights Reserved.  This information is to be used exclusively as an
online learning aid.  Any attempts to copy, reproduce, or use for training is strictly prohibited.
Courseware
Training Resources
Tutorials