views:

37

answers:

1

I have a COM component having a MyDataObject class. There is a method with the following signature:

HRESULT MyDataObject::GetData(long Format, VARIANT* retval)

This COM object is used in a .NET application and the method returns either a string or byte array depending on Format value. The returned value is converted to a byte[] in .NET and used.

I suspect this method is leaking memory i.e. The byte array returned from this method needs to be freed up somehow. When I debug the application, I see the GetData(...) method call taking up memory on each call. I am not sure how to free up this memory, Can I change it to hGlobal and then call ReleaseHGlobal(...) or is there any other way?

UPDATED


Yes, I am using Task Manager to see how much memory is being used by the sample application. When I start the application, it stays at 16MB but as soon as I hit the test button to call this GetData(...) method about 850 times, the memory starts increasing and the TaskManager shows the application's memory usage increased by about 25MB.

+1  A: 

The COM interop layer in the CLR already frees the variant after copying its value into an object. Even if you would want to call Marshal.FreeCoTaskMem() you can't, you cannot get a reference to the original variant.

You didn't say how you concluded that you've got a memory leak. Don't use Taskmgr.exe, it will give you the wrong impression. Make sure you've got a real leak by calling this method millions of times in a small test program. If memory usage doesn't grow without bound and eventually cause OOM then you don't have a real leak. If it does crash then suspect the COM server of the leak. Like allocating both the string and the array but returning only one of them.

Hans Passant
I've added some more details to the original post. If Task Manager gives a wrong impression then do you know of any other tool that can be used to monitor the correct memory usage of an application. Also, when the method is called in the main application (not the sample), it increases the memory (in TaskManager) after each operation i.e. 850 calls. The memory does not seem to come down which I guess means that it is being held by this COM component. This gives a bad impression about the application in terms of memory usage.
A9S6
I don't know what 850 calls will do. I *really* did mean a million.
Hans Passant
"The COM interop layer in the CLR already frees the variant after copying its value into an object"...Can you point me to some articles where this behavior is explained?
A9S6
Accepted as an answer. I used the Performance Monitor application to check both the .NET Managed Heap Size and the Private Bytes of the main application. It clearly showed that the COM was holding memory after each call because the private bytes kept increasing.
A9S6