Click here to Skip to main content
15,881,882 members
Articles / Programming Languages / C#
Alternative
Tip/Trick

Proper Way of Releasing COM Objects in .NET

Rate me:
Please Sign up or sign in to vote.
4.93/5 (7 votes)
2 Aug 2011CPOL1 min read 48.1K   8   4
Please let me suggest that "FinalReleaseComObject" is not the way to go. If you write structured code, you should never need it. Strictly following Microsoft Patterns & Practices:1) Declare & instantiate COM objects at the last moment possible.2) ReleaseComObject(obj) for ALL...
Please let me suggest that "FinalReleaseComObject" is not the way to go. If you write structured code, you should never need it.

Strictly following Microsoft Patterns & Practices:

1) Declare & instantiate COM objects at the last moment possible.
2) ReleaseComObject(obj) for ALL objects, at the soonest moment possible.
3) Always ReleaseComObject in the opposite order of creation.
4) NEVER call GC.Collect() except when required for debugging.

All of these things are documented on MSDN. Upon following these simple rules, .NET will optimize garbage collection along the way, minimizing memory/garbage load, and improving your overall application performance.

WARNING:
GC.Collect will stop all .NET process in the OS to collect garbage. With each call to GC.Collect, you may promote garbage from Generation 0 to Generation 1 and then to Generation 2. Once your garbage reaches Generation 2, you must terminate your process to recover memory.

Finally, your code may require calling GC.Collect to get around leaky code. You can unknowingly leak hidden COM objects into garbage just by taking legitimate coding shortcuts. For example:

Imagine a COM function that does work, and returns a COM object.

C#
(comClass.comObject) myCom.ProcessError(errorNumber);


Your code doesn't want the resulting object, it just wants to process the error:

C#
myCom.ProcessError(5);
Marshal.ReleaseComObject(myCom);


The returned COM object is sent to .NET garbage, keeping a handle to myCom from garbage.


Until GC naturally occurs, myCom will not be fully released. This is why so many people need to force object destruction using FinalReleaseComObject() and GC.Collect(). Both are required for dirty Interop code.

A CLEAN version of this code:

C#
Marshal.ReleaseComObject( myCom.ProcessError (5) ); //Release returned object
Marshal.ReleaseComObject( myCom);


There are many other shortcuts where you ignore items in collections, and when you follow certain COM objects chains where you can leak intermediate objects. Again, please refer to Microsoft Patterns and Practices.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect Anodyne Enterprise Security
United States United States
I've spent the last 30+ years building secure, durable code in government, healthcare, and critical infrastructure industries, from FORTRAN 4 to C#, on databases from pre-SQL ISAM ones to Oracle 12, and on platforms from VMS to Linux (not to exclude all common permutations by Microsoft). In my spare time, I teach classes on whole-system design principles from configuring SANS, programming switches, to advanced principles in C# for creating secure, durable code. I am CISSP and CCSP certified, regularly working with legal teams to validate Cloud security and regulatory compliance.

Comments and Discussions

 
GeneralCalling GC.Collect() is not a good idea. Pin
Pranit Kothari6-Nov-11 7:14
Pranit Kothari6-Nov-11 7:14 
GeneralRe: GC.Collect() should <i><b>never </b></i>be used in productio... Pin
Crooked Path7-Nov-11 3:27
Crooked Path7-Nov-11 3:27 
GeneralTrue... not an alternate, but once I clicked "submit", I fou... Pin
Crooked Path4-Aug-11 2:57
Crooked Path4-Aug-11 2:57 
GeneralThank you for the reply. Actually it is not quite an "alter... Pin
wmjordan3-Aug-11 15:28
professionalwmjordan3-Aug-11 15:28 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.