1

Folks - I'm creating many COM servers (I'm launching numerous EXEs) in .net, talking to COM via COM -interop, using numerous COM objects in the server, etc. If I kill the process, is there any harm? Is there anything bad about NOT releasing all the COM objects I've used via Marshal.FinalReleaseComObject()? Will I have a memory leak over time?

Suraj
  • 35,905
  • 47
  • 139
  • 250

1 Answers1

3

I'll assume you are talking about out-of-process COM servers although they are far less common than in-process servers. Killing the client app is bad, the server will never get the release calls, the resources for any objects that the client allocated will stay in use until the EXE is terminated. Killing the server app is going to make the client app fail with RPC errors, nothing is leaked.

There's nothing bad about not using Marshal.FinalReleaseComObject(), COM object reference counts are managed by the RCW (runtime callable wrapper). It is a managed object like any other in .NET programming, the garbage collector takes care of it. The reference count is decremented when the finalizer runs. It is unpredictable when that happens.

Using Final/ReleaseComObject() can make it predictable but you have to call it on every object you create. Which can be difficult, it isn't always obvious that you created one when you use the indexer for example. It is also dangerous, mis-timing the call or not properly tracking all references to the object causes the infamous "COM object that has been separated from its underlying RCW cannot be used" exception. A good war story is available here.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Hi Hans. Correct, I am talking about out-of-process COM sever. Agreed, killing client (we mean .net app right?) is bad. When you say killing the server app (COM app) is going to make the client app fail with RPC errors, that only applies if trying to make calls to the server, correct? If the server process is killed, and no more calls are made to the server, then .net will garbage-collect any resources and the world is a nice place? – Suraj Mar 10 '11 at 13:51
  • Not really. Creating *one* object in the client is enough to get the RPC error. There will always be an (otherwise invisible) call to release it. The GC does it. Only killing it when the client isn't using the server at all is safe. Which is obvious. – Hans Passant Mar 10 '11 at 14:00
  • sorry...I'm having trouble following your last comment. Perhaps we can take a concrete example of Excel Automation. To launch the Excel exe, its necessary to instantiate an Excel Application object (var app = new Application()). Then we can do all sorts of fancy things like Application.Workbooks[0].Worksheets[0].Range["A1"] = "123". So .net is client, Excel is server. If I kill Excel.exe in taskmanager and I make NO MORE calls to app, then there is no possibility of RPC error and GC will cleanup the mess? – Suraj Mar 10 '11 at 15:07
  • GC cleans messes by releasing the Application object and any other RCW your code uses. There will be an RPC error on the Release() call, the CLR however does seem to ignore it when I tested this. Kinda makes sense, no real need to complain about a "server is gone" error on a release call. – Hans Passant Mar 10 '11 at 15:21