all groups > dotnet interop > may 2005 >
You're in the

dotnet interop

group:

Foreach and object leak


Foreach and object leak Ed
5/31/2005 11:00:45 PM
dotnet interop:
We have an VB.Net application that uses a COM automation server. There is an
object leak that we don't know how to solve.

objColl = autoServer.TheCollection
foreach objMember in objColl
.
.
.
System.Runtime.InteropServices.Marshal.ReleaseComObject(objMember)
next
System.Runtime.InteropServices.Marshal.ReleaseComObject(objColl)

The problem is that foreach creates a hidden reference to IEnumerate (if I
remember the name correctly) that we don't how to pass to ReleaseComObject.
That causes leam for all the members in the collection.

Any solution?

Thanks

Re: Foreach and object leak Sean Hederman
6/1/2005 12:00:00 AM
[quoted text, click to view]

Are you sure there's a memory leak? Generally speaking ReleaseComObject does
not have to be called manually, since the framework will take care of the
AddRef/Release in the RCW's Finalize, admittedly this will be
non-deterministic, but it should still keep IEnumerate from leaking.

Re: Foreach and object leak Ed
6/1/2005 4:25:54 PM

[quoted text, click to view]
Thanks for the reply. I agree there is not leak. I did not express the
problem correctly.

The object is released eventually during the garbage collection. What we
have to do is to release it right after the Foreach loop or at least when
the method containing the Foreach return. The automation server does not
function correctly if the release is left for the GC. Calling Collect on GC
after each cal to this method works but we want to avoid the overhead.

Re: Foreach and object leak Sean Hederman
6/2/2005 6:49:08 AM
[quoted text, click to view]

Then I'm afraid you'll have to do this manually:

objColl = autoServer.TheCollection
IEnumerator enumerator = objColl.GetEnumerator();
while(enumerator.MoveNext()) {
MemberType objMember = (MemberType) enumerator.Current;
...
System.Runtime.InteropServices.Marshal.ReleaseComObject(objMember)
}
System.Runtime.InteropServices.Marshal.ReleaseComObject(enumerator)
System.Runtime.InteropServices.Marshal.ReleaseComObject(objColl)

If there's any bugs in the above, my bad, I'm tired and grumpy ;-)

Re: Foreach and object leak Ed
6/2/2005 8:52:47 AM

[quoted text, click to view]

I tried that but ReleaseComObject(enumerator) throws a "Specified cast is
not valid" exception.

Re: Foreach and object leak Ed
6/3/2005 11:22:27 AM

[quoted text, click to view]

It was a life saver.

Thanks.

Re: Foreach and object leak Sean Hederman
6/3/2005 5:08:33 PM
[quoted text, click to view]

Whoops, my bad! Yeah, enumerator is not actually an RCW, it's a customer
marshaller that contains the RCW.

Do the following:
object rcwEnumerator = ((ICustomAdapter) enumerator).GetUnderlyingObject();
System.Runtime.InteropServices.Marshal.ReleaseComObject(rcwEnumerator);

AddThis Social Bookmark Button