Basic Memory Housekeeping (.NET Memory Management: Part 1)

April 3, 2008 Rick Minerich

This is the first in a series of posts I will be writing about managing memory in .NET. Before I move on to more complex techniques, I thought it would be good to cover the basics.

Articles in This Series

Part 1 - Basic Housekeeping
Part 2 - Improving Performance Through Stack Allocation
Part 3 - Increasing the Size of the Stack
Part 4 - Garbage Collector Settings  
Part 5 - Changing Your Garbage Collector Settings on the Fly

Disposing IDisposable Objects

When an object implements IDisposable you can explicitly determine when it is finalized. In fact, IDisposable objects sometimes will not release unmanaged data unless they are explicitly told to and so can leak memory if not handled properly. If at all possible it is best to use IDisposable objects inside a using statement: 

using (AtalaImage img = new AtalaImage(@"C:\File.png"))
{
    ...
} 

A using statement will ensure at the object is cleaned up even if an exception is thrown or a method is terminated unexpectedly.  If the object needs to be kept around for an indeterminate amount of time be sure to call the Dispose() method when you are done with it. 

class MyClass
{
    AtalaImage img;
 
    public void NewImage(string filename)
    {
        if (img != null)
            img.Dispose();
        img = new AtalaImage(filename);
    }
public void Clean()
    {
        if (img != null)
            img.Dispose();
    }
}

Please note that this is a toy example. In most cases you should implement the IDisposable pattern yourself when keeping references to IDisposable objects. See Steve's article IDisposable Made E-Z for more information.
 

Forcing Garbage Collection

Sometimes when a lot of memory is needed it can help a lot to stop and let the garbage collector clean things up first. This is fairly simple to do: 

GC.Collect();
GC.WaitForPendingFinalizers(); 

 

Collect will force garbage collection for all objects without strong references. WaitForPendingFinalizers will cause the execution of your current thread to wait for the garbage collector to finish processing everything in its queue. After these calls are finished running your heap will be as clean as possible.
 

Using Structs instead of Classes

The overhead caused by using classes can chew up a ton of memory in cases where a lot of small objects are needed. Jim Mischel at informIT did a test in which he found that Classes can take up to eight times the memory of a Struct. Structs are also handy because they can be allocated without the new parameter and so be put on the stack instead of the heap. This being on the stack gives Structs several good properties not the least of which is that everything on the stack goes away when its method is exited and so the garbage collector is avoided entirely.
 

Additional Information

If you want to learn more about Structs check out the MSDN tutorial here.
If you want to learn more about the different between the stack and the heap check out this C# corner article by Matthew Cochran.
To learn more about Programming for Garbage Collection check out this article of the same name on MSDN.
 
4/4/08 Edit: Fixed a small problem with my IDisposable example.

About the Author

Rick Minerich

Rick Minerich is a former Software Architect at Atalasoft, F# MVP, and is currently the Director of Research and Development at Bayard Rock. To read more articles from Rick please visit his blog: www.richardminerich.com

Follow on Twitter More Content by Rick Minerich
Previous Article
Improving Performance Through Stack Allocation (.NET Memory Management: Part 2)
Improving Performance Through Stack Allocation (.NET Memory Management: Part 2)

Articles in This Series Part 1 – Basic Housekeeping Part 2 –...

No More Articles

Try any of our Imaging SDKs free for 30 days with Full Support

Download Now