Proper way of releasing COM objects? - c#

Sometimes when I end the application and it tries to release some COM objects, I receive a warning in the debugger:
RaceOnRCWCleanUp was detected
If I write a class which uses COM objects, do I need to implement IDisposable and call Marshal.FinalReleaseComObject on them in IDisposable.Dispose to properly release them?
If Dispose is not called manually then, do I still need to release them in the finalizer or will the GC release them automatically? Now I call Dispose(false) in the finalizer but I wonder if this is correct.
The COM object I use also have an event handler which the class listens to. Apparently the event is raised on another thread, so how do I correctly handle it if it is fired when disposing the class?

First - you never have to call Marshal.ReleaseComObject(...) or Marshal.FinalReleaseComObject(...) when doing Excel interop. It is a confusing anti-pattern, but any information about this, including from Microsoft, that indicates you have to manually release COM references from .NET is incorrect. The fact is that the .NET runtime and garbage collector correctly keep track of and clean up COM references.
Second, if you want to ensure that the COM references to an out-of-process COM object is cleaned up when your process ends (so that the Excel process will close), you need to ensure that the Garbage Collector runs. You do this correctly with calls to GC.Collect() and GC.WaitForPendingFinalizers(). Calling twice is safe, end ensures that cycles are definitely cleaned up too.
Third, when running under the debugger, local references will be artificially kept alive until the end of the method (so that local variable inspection works). So a GC.Collect() calls are not effective for cleaning object like rng.Cells from the same method. You should split the code doing the COM interop from the GC cleanup into separate methods.
The general pattern would be:
Sub WrapperThatCleansUp()
' NOTE: Don't call Excel objects in here...
' Debugger would keep alive until end, preventing GC cleanup
' Call a separate function that talks to Excel
DoTheWork()
' Now Let the GC clean up (twice, to clean up cycles too)
GC.Collect()
GC.WaitForPendingFinalizers()
GC.Collect()
GC.WaitForPendingFinalizers()
End Sub
Sub DoTheWork()
Dim app As New Microsoft.Office.Interop.Excel.Application
Dim book As Microsoft.Office.Interop.Excel.Workbook = app.Workbooks.Add()
Dim worksheet As Microsoft.Office.Interop.Excel.Worksheet = book.Worksheets("Sheet1")
app.Visible = True
For i As Integer = 1 To 10
worksheet.Cells.Range("A" & i).Value = "Hello"
Next
book.Save()
book.Close()
app.Quit()
' NOTE: No calls the Marshal.ReleaseComObject() are ever needed
End Sub
There is a lot of false information and confusion about this issue, including many posts on MSDN and on StackOverflow.
What finally convinced me to have a closer look and figure out the right advice was this post https://blogs.msdn.microsoft.com/visualstudio/2010/03/01/marshal-releasecomobject-considered-dangerous/ together with finding the issue with references kept alive under the debugger on some StackOverflow answer.

Based on my experience using different COM objects (in-process or out-of-process) I would suggest one Marshal.ReleaseComObject per one COM/ .NET boundary crossing (if for an instance you reference COM object in order to retrieve another COM reference).
I have run into many issues just because I decided to postpone COM interop cleanup to GC.
Also please notice, I never use Marshal.FinalReleaseComObject - some COM objects are singletons and it doesn't work well with such objects.
Doing anything in managed objects inside finalizer (or Dispose(false) from the well-known IDisposable implementation) is forbidden. You must not rely on any .NET object reference in the finalizer. You can release IntPtr, but not COM object as it could already be clean up.

There's an article here on that: http://www.codeproject.com/Tips/235230/Proper-Way-of-Releasing-COM-Objects-in-NET
In a nutshell:
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.
Until GC naturally occurs, the com reference 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.
Dispose is NOT automatically called by the GC. When an object is being disposed, the destructor is called (in a different thread). This is usually where you could release any unmanaged memory, or com references.
Destructors: http://msdn.microsoft.com/en-us/library/66x5fx1b.aspx
... when your application encapsulates unmanaged resources such as windows, files, and network connections, you should use destructors to free those resources. When the object is eligible for destruction, the garbage collector runs the Finalize method of the object.

Related

Releasing Com Objects Doesnt Affect Memory Usage

When I release com objects by Marshall.ReleaseComObject method, memory usage of application doesnt change. Instead of using Marshall.ReleaseComObject, using Garbage Collector (GC.Collect()) can release memory area of com objects but the UI is getting slow down.
So my question is, what is the best method to release com objects?
Athough a bit outdated (as from ArcGIS 10.0) the rules for releasing and how to do so are pretty well described on http://help.arcgis.com/en/sdk/10.0/arcobjects_net/conceptualhelp/index.html#/Releasing_COM_references/0001000004tm000000/.
There are two ways to do this. Either by using Marshal.ReleaseCOMObject or by the ComReleaser-class which essentially is a wrapper around the former. However you may have multiple references to the exact same com-object, which is why calling ReleaseComObject will not finally release the object, but simply decrease the internal reference-counter by one. Only when that counter is equal to zero the object will actually be released. See here for example:
var f1 = featureClass.GetFeature(1);
// retrieve the exact same feature again
var f2 = featureClass.GetFeature(1);
Although from a .NET-perspective f1 and f2 are comlpletely different objects, the underlying com-object is the same (assuming unique-instancing, which is out of the scope of this question). When calling Marshal.ReleaseComObject on either f1 or f2, you will only decrease the internal reference-counter for this com-object by one, leaving one reference alive.
GC.Collect however has no effect as it can´t handle unmanaged resources which com-objects are. The garbage-collector is only able to release managed resources. Calling GC.Collect will thus only - if at all - release the runtime-callable-wrapper, which is a managed wrapper around the unmanaged object. The latter however still exists in memory and is likely to produce a dead-leak.
Having said this the only way to finally release a com-objects is to call Marshal.ReleaseComObject in a loop until the reference-counter is zero.
while(Marshal.ReleaseComObject(myObject) > 0);
Afterwards you may or may not call GC.Collect. However I won´t suggest to do so, as the garbage-collector knows best when to release a mananed object. Forcing it to do so will at best work as expected, at worst however only mke your code slow without having any positive effect. GC is un-determinsitc process, you can´t really influence it.
Best way to do is using ComReleaser or Marshal.ReleaseComObject methods. Calling GC.Collect method too much will cause to slow down of your application. Let GC do its job when needed.
Try this,
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oApp);
oApp = null; // Set each COM Object to null
//
// After all of the COM objects have been released and set to null, do the following:
GC.Collect(); // Start .NET CLR Garbage Collection
GC.WaitForPendingFinalizers(); // Wait for Garbage Collection to finish
If object implement finalizer, call gc means put this object reference in finalization queue, means it doesnt release immediately.

Where can I find more detail on disposal of COM resources in .NET?

The background for my question is this: I am converting a message processing app that uses many COM components from VB6 to C#. Many of the COM components in the application are fine-grained components that are used in high numbers and frequency within message processing loops. I am seeing a massive (and progressively growing) increase in memory usage when processing a set of test messages in the C# app as compared to the VB6 app. I used a memory profiler on the application that confirmed that the high memory usage was due to live instances of COM objects on the application's unmanaged heap. I know that these components are not being "leaked" due to live references because if I put a GC.Collect() at the core of the message processing loop, the memory usage is flat and nearly identical to the VB6 app (although the performance degrades horribly as one would expect).
I have read everything I can find on the multi-generation garbage collector in C#, runtime callable wrappers, unmanaged resource memory allocation, Marshal.ReleaseComObject(), Marshal.FinalReleaseComObject(), etc. None of it explains why the application is holding onto live COM objects in the unmanaged heap when the corresponding RCWs are eligible for garbage collection.
In some articles, I have seen allusions to the possibility that the actual implementation of the garbage collector in C# may involve optimizations such as not performing collection of all eligible objects in a particular generation. If this or something like it were true, it could explain why eligible RCWs and their corresponding COM objects are not collected and destroyed. Another explanation could be if the destruction of a COM object in the unmanaged heap is not directly tied to the collection of its corresponding RCW. I have not found anything that offers this degree of detail on how COM objects are handled in .NET. I need to understand this better because my app's memory usage is currently unacceptable. Any pointers or recommendations would be greatly appreciated.
Edit: I should add that I am quite familiar with finalizers (which are not documented to exist on RCWs) and the IDisposable interface (which RCWs do not implement). To the best of my understanding, Marshal.ReleaseComObject() is the proper method of explicitly "disposing" of a COM reference. I was careful to add that statement for every known usage of a COM object in my app and it resulted in no difference in memory usage.
Further, it is not clear why a lack of disposal or finalization code could be the problem when the addition of an explicit GC.Collect() results in no memory problems. Neither Dispose() nor the presence of a finalizer result in the actual collection of objects. The former permits an object to suppress its finalization step (if any) and the latter allows for the cleanup of unmanaged resources of which none are exposed in an RCW.
Are you implementing IDisposable properly in the classes that instantiate your COM objects?
You need to implement IDisposable and dispose of your COM RCW's in the Dispose() method. Then all code that instantiates classes that implement IDisposable should call it either explicitly or by using a using() statement, like so:
var first = new DisposableObject();
...
first.Dispose();
and
using(var first = new DisposableObject())
{
...
}
IDisposable is the only way to get the CLR to dispose of these objects in a timely manner and to make sure you lose COM references.
Use a Finalizer or destructor to clean up the memory used by the COM objects.
http://msdn.microsoft.com/en-us/library/66x5fx1b.aspx
Alternatively, if you want the objects to clean up immediately, you can implement IDispose, and use a using statement in your code that instantiates the COM object.

What happens if I don't call Dispose on the pen object?

What happens if I don't call Dispose on the pen object in this code snippet?
private void panel_Paint(object sender, PaintEventArgs e)
{
var pen = Pen(Color.White, 1);
//Do some drawing
}
A couple of corrections should be made here:
Regarding the answer from Phil Devaney:
"...Calling Dispose allows you to do deterministic cleanup and is highly recommended."
Actually, calling Dispose() does not deterministically cause a GC collection in .NET - i.e. it does NOT trigger a GC immediately just because you called Dispose(). It only indirectly signals to the GC that the object can be cleaned up during the next GC (for the Generation that the object lives in). In other words, if the object lives in Gen 1 then it wouldn't be disposed of until a Gen 1 collection takes place. One of the only ways (though not the only) that you can programmatically and deterministically cause the GC to perform a collection is by calling GC.Collect(). However, doing so is not recommended since the GC "tunes" itself during runtime by collecting metrics about your memory allocations during runtime for your app. Calling GC.Collect() dumps those metrics and causes the GC to start its "tuning" all over again.
Regarding the answer:
IDisposable is for disposing unmanaged resources. This is the pattern in .NET.
This is incomplete. As the GC is non-deterministic, the Dispose Pattern, (How to properly implement the Dispose pattern), is available so that you can release the resources you are using - managed or unmanaged. It has nothing to do with what kind of resources you are releasing. The need for implementing a Finalizer does have to do with what kind of resources you are using - i.e. ONLY implement one if you have non-finalizable (i.e. native) resources. Maybe you are confusing the two. BTW, you should avoid implementing a Finalizer by using the SafeHandle class instead which wraps native resources which are marshaled via P/Invoke or COM Interop. If you do end up implementing a Finalizer, you should always implement the Dispose Pattern.
One critical note which I haven't seen anyone mention yet is that if disposable object is created and it has a Finalizer (and you never really know whether they do - and you certainly shouldn't make any assumptions about that), then it will get sent directly to the Finalization Queue and live for at least 1 extra GC collection.
If GC.SuppressFinalize() is not ultimately called, then the finalizer for the object will be called on the next GC. Note that a proper implementation of the Dispose pattern should call GC.SuppressFinalize(). Thus, if you call Dispose() on the object, and it has implemented the pattern properly, you will avoid execution of the Finalizer. If you don't call Dispose() on an object which has a finalizer, the object will have its Finalizer executed by the GC on the next collection. Why is this bad? The Finalizer thread in the CLR up to and including .NET 4.6 is single-threaded. Imagine what happens if you increase the burden on this thread - your app performance goes to you know where.
Calling Dispose on an object provides for the following:
reduce strain on the GC for the process;
reduce the app's memory pressure;
reduce the chance of an OutOfMemoryException (OOM) if the LOH (Large Object Heap) gets fragmented and the object is on the LOH;
Keep the object out of the Finalizable and f-reachable Queues if it has a Finalizer;
Make sure your resources (managed and unmanaged) are cleaned up.
Edit:
I just noticed that the "all knowing and always correct" MSDN documentation on IDisposable (extreme sarcasm here) actually does say
The primary use of this interface is
to release unmanaged resources
As anyone should know, MSDN is far from correct, never mentions or shows 'best practices', sometimes provides examples that don't compile, etc. It is unfortunate that this is documented in those words. However, I know what they were trying to say: in a perfect world the GC will cleanup all managed resources for you (how idealistic); it will not, however cleanup unmanaged resources. This is absolutely true. That being said, life is not perfect and neither is any application. The GC will only cleanup resources that have no rooted-references. This is mostly where the problem lies.
Among about 15-20 different ways that .NET can "leak" (or not free) memory, the one that would most likely bite you if you don't call Dispose() is the failure to unregister/unhook/unwire/detach event handlers/delegates. If you create an object that has delegates wired to it and you don't call Dispose() (and don't detach the delegates yourself) on it, the GC will still see the object as having rooted references - i.e. the delegates. Thus, the GC will never collect it.
#joren's comment/question below (my reply is too long for a comment):
I have a blog post about the Dispose pattern I recommend to use - (How to properly implement the Dispose pattern). There are times when you should null out references and it never hurts to do so. Actually, doing so does do something before GC runs - it removes the rooted reference to that object. The GC later scans its collection of rooted references and collects those that do not have a rooted reference. Think of this example when it is good to do so: you have an instance of type "ClassA" - let's call it 'X'. X contains an object of type "ClassB" - let's call this 'Y'. Y implements IDisposable, thus, X should do the same to dispose of Y. Let's assume that X is in Generation 2 or the LOH and Y is in Generation 0 or 1. When Dispose() is called on X and that implementation nulls out the reference to Y, the rooted reference to Y is immediately removed. If a GC happens for Gen 0 or Gen 1, the memory/resources for Y is cleaned up but the memory/resources for X is not since X lives in Gen 2 or the LOH.
The Pen will be collected by the GC at some indeterminate point in the future, whether or not you call Dispose.
However, any unmanaged resources held by the pen (e.g., a GDI+ handle) will not be cleaned up by the GC. The GC only cleans up managed resources. Calling Pen.Dispose allows you to ensure that these unmanaged resources are cleaned up in a timely manner and that you aren't leaking resources.
Now, if the Pen has a finalizer and that finalizer cleans up the unmanaged resources then those said unmanaged resources will be cleaned up when the Pen is garbage collected. But the point is that:
You should call Dispose explicitly so that you release your unmanaged resources, and
You shouldn't need to worry about the implementation detail of if there is a finalizer and it cleans up the unmanaged resources.
Pen implements IDisposable. IDisposable is for disposing unmanaged resources. This is the pattern in .NET.
For previous comments on the this topic, please see this answer.
The underlying GDI+ pen handle will not be released until some indeterminate time in the future i.e. when the Pen object is garbage collected and the object's finalizer is called. This might not be until the process terminates, or it might be earlier, but the point is its non-deterministic. Calling Dispose allows you to do deterministic cleanup and is highly recommended.
The total amount of .Net memory in use is the .Net part + all 'external' data in use. OS objects, open files, database and network connections all take some resources that are not purely .Net objects.
Graphics uses Pens and other objects wich are actually OS objects that are 'quite' expensive to keep around. (You can swap your Pen for a 1000x1000 bitmap file). These OS objects only get removed from the OS memory once you call a specific cleanup function. The Pen and Bitmap Dispose functions do this for you immediatly when you call them.
If you don't call Dispose the garbage collector will come to clean them up 'somewhere in the future*'.
(It will actually call the destructor/finalize code that probably calls Dispose())
*on a machine with infinite memory (or more then 1GB) somewhere in the future can be very far into the future. On a machine doing nothing it can be easily longer then 30 minutes to clean up that huge bitmap or very small pen.
If you really want to know how bad it is when you don't call Dispose on graphics objects you can use the CLR Profiler, available free for the download here. In the installation folder (defaults to C:\CLRProfiler ) is CLRProfiler.doc which has a nice example of what happens when you don't call Dispose on a Brush object. It is very enlightening. The short version is that graphics objects take up a larger chunk of memory than you might expect and they can hang around for a long time unless you call Dispose on them. Once the objects are no longer in use the system will, eventually, clean them up, but that process takes up more CPU time than if you had just called Dispose when you were finished with the objects.
You may also want to read up on using IDisposable here and here.
It will keep the resources until the garbage collector cleans it up
Depends if it implements finalizer and it calls the Dispose on its finalize method. If so, handle will be released at GC.
if not, handle will stay around until process is terminated.
With graphic stuff it can be very bad.
Open the Windows Task Manager. Click "choose columns" and choose column called "GDI Objects".
If you don't dispose certain graphic objects, this number will keep raising and raising.
In older versions of Windows this can crash the whole application (limit was 10000 as far as I remember), not sure about Vista/7 though but it's still a bad thing.
the garbage collector will collect it anyway BUT it matters WHEN:
if you dont call dispose on an object that you dont use it will live longer in memory and gets promoted to higher generations meaning that collecting it has a higher cost.
in back of my mind first idea came to the surface is that this object will be disposed as soon as the method finishes execution!, i dont know where did i got this info!, is it right?

How to deallocate COM server object forcefully from C# .NET

Can I know how to deallocate COM server object forcefully from C# .NET if particular condion fails or the object is partially constructed?
The problem is I am using that COM server using DCOM mechanism; in the worst case, when the object is not created fully and I am coming out of application since failure, the COM object is still in memory (showed in COM+ Application component services). If its going beyond some limits, it leads to memory leak and crash. But if its manageable amount of failures, its getting deleted after some point of times.
Sample:-
Calculator.App objApp = new Calculator.App();
if( !obj.CanBeUsed() )
{
//how to deallocate the COM object objApp
}
Note:
There is a method GC.Collect() used by Garbase Collector to de-allocate from the heap memory forcefully. Whether I can use this method or .NET franework is giving anyother solution for this particular case?
Like this:
System.Runtime.InteropServices.Marshal.ReleaseComObject(objApp);
You should try Marshal.FinalReleaseComObject method.
The FinalReleaseComObject method
releases the managed reference to a
COM object. Calling this method is
equivalent to calling the
ReleaseComObject method in a loop
until it returns 0 (zero).
When the reference count on the COM
object becomes 0, the COM object is
usually freed, although this depends
on the COM object's implementation and
is beyond the control of the runtime.
However, the RCW can still exist,
waiting to be garbage-collected.
The COM object cannot be used after it
has been separated from its underlying
RCW. If you try to call a method on
the RCW after its reference count
becomes 0, a InvalidComObjectException
will be thrown.

Release resources in .Net C#

I'm new to C# and .NET, ,and have been reading around about it.
I need to know why and when do I need to release resources? Doesn't the garbage collector take care of everything? When do I need to implement IDisposable, and how is it different from destructor in C++?
Also, if my program is rather small i.e. a screensaver, do I need to care about releasing resources?
Thanks.
The garbage collector is only aware of memory. That's fine for memory, because one bit of memory is pretty much as good as any other, so long as you've got enough of it. (This is all modulo cache coherency etc.)
Now compare that with file handles. The operating system could have plenty of room to allocate more file handles - but if you've left a handle open to a particular file, no-one else will be able to open that particular file for writing. You should tell the system when you're done with a handle - usually by closing the relevant stream - as soon as you're finished, and do so in a way that closes it even if an exception is thrown. This is usually done with a using statement, which is like a try/finally with a call to Dispose in the finally block.
Destructors in C++ are very different from .NET finalizers, as C++ destructors are deterministic - they're automatically called when the relevant variable falls out of scope, for example. Finalizers are run by the garbage collector at some point after an object is no longer referenced by any "live" objects, but the timing is unpredictable. (In some rare cases, it may never happen.)
You should implement IDisposable yourself if you have any clean-up which should be done deterministically - typically that's the case if one of your instance variables also implements IDisposable. It's pretty rare these days to need to implement a finalizer yourself - you usually only need one if you have a direct hold on operating system handles, usually in the form of IntPtr; SafeHandle makes all of this a lot easier and frees you from having to write the finalizer yourself.
Basically, you need to worry about releasing resources to unmanaged code - anything outside the .NET framework. For example, a database connection or a file on the OS.
The garbage collector deals with managed code - code in the .NET framework.
Even a small application may need to release unmanaged resources, for example it may write to a local text file. When you have finished with the resource you need to ensure the object's Dispose method is called. The using statement simplifies the syntax:
using (TextWriter w = File.CreateText("test.txt"))
{
w.WriteLine("Test Line 1");
}
The TextWriter object implements the IDisposable interface so as soon as the using block is finished the Dispose method is called and the object can be garbage collected. The actual time of collection cannot be guaranteed.
If you create your own classes that need to be Disposed of properly you will need to implement the IDisposable interface and Dispose pattern yourself. On a simple application you probably won't need to do this, if you do this is a good resource.
Resources are of two kinds - managed, and unmanaged. Managed resources will be cleaned up by the garbage collector if you let it - that is, if you release any reference to the object. However, the garbage collection does not know how to release unmanaged resources that a managed object holds - file handles, and other OS resources for example.
IDisposable is best practice when there's a managed resource you want released promptly (like a database connection), and vital when there are unmanaged resources which you need to have released. The typical pattern:
public void Dispose()
protected void Dispose(bool disposing)
Lets you ensure that unmanaged resources are released whether by the Dispose method or by object finalisation.
You don't need to release memory in managed objects like strings or arrays - that is handled by the garbage collector.
You should clean up operating system resources and some unmanaged objects when you have finished using them. If you open a file you should always remember to close that file when you have finished using it. If you open a file exclusively and forget to close, the next time you try to open that file it might still be locked. If something implements IDisposable, you should definitely consider whether you need to close it properly. The documentation will usually tell you what the Dispose method does and when it should be called.
If you do forget, the garbage collector will eventually run the finalizer which should clean up the object correctly and release the unmanaged resources, but this does not happen immediately after the object becomes eligible for garbage collection, and it in fact might not run at all.
Also it is useful to know about the using statement.
The garbage collector releases MEMORY and cleans up - through disposition - elemetns it removes. BUT: IT only does so when it has memory pressure.
THis is seriously idiotic for ressources whree I may want to explicitely release them. Save to file, for example, is supposed to: Open the file, write out the data and - close the file, so it can be copied away by the user if he wants, WITHOUT waiting for the GC to come around and release the memory for the file object, which may not happen for hours.
You only need to worry about precious resources. Most objects you create while programming do not fit into this category. As you say, the garbage collector will take care of these.
What you do need to be mindful of is objects that implement IDisposable, which is an indication that the resources it owns are precious and should not wait for the finalizer thread to be cleaned up. The only time you would need to implement IDisposable is on classes that own a) objects that implement IDisposable (such as a file stream), or b) unmanaged resources.

Categories