Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Another memory leak question

74 views
Skip to first unread message

Piers Lawson

unread,
Oct 22, 2003, 6:45:25 PM10/22/03
to
Hi All

I'm writing a DirectX 9 application that will grab a frame
from a webcam once every 10 seconds or so. The app seems
to work fine except that with each snap shot taken, the
memory ratchets up and never comes down. The memory leak
is around 800k for each picture.

To find the leak, I have commented all my code out and
gradually add it back in. The code is actually written in
C# with a library providing a simple wrapper around
DirectX. I'm pretty sure this isn't the problem.

The following is pseudo code that does not leak:

while(1)
{
object capObj = null;
Guid gbf = typeof(IBaseFilter).GUID;
DeviceMonikor.BindToObject(null, null, ref gbf, out
capObj);
capFilter = (IBaseFilter) capObj;
capObj = null;

comType = Type.GetTypeFromCLSID(Clsid.FilterGraph);
comObj = Activator.CreateInstance(comType);
graphBuilder = (IGraphBuilder) comObj;
comObj = null;

Guid clsid = Clsid.CaptureGraphBuilder2;
Guid riid = typeof(ICaptureGraphBuilder2).GUID;
comObj = DsBugWO.CreateDsInstance(ref clsid, ref riid);
capGraph = (ICaptureGraphBuilder2) comObj;
comObj = null;

comType = Type.GetTypeFromCLSID(Clsid.SampleGrabber);
comObj = Activator.CreateInstance(comType);
sampGrabber = (ISampleGrabber) comObj;
comObj = null;

// Do nothing

Marshal.ReleaseComObject(graphBuilder);
graphBuilder = null;

Marshal.ReleaseComObject(sampGrabber);
sampGrabber = null;

Marshal.ReleaseComObject(capFilter);
capFilter = null;

Marshal.ReleaseComObject(capGraph);
capGraph = null;

GC.Collect();

sleep(10000)
}

I would have been very worried if the above had leaked, as
it simply creates the objects and destroys them! However,
if I replace the "// Do nothing" comment with:

capGraph.SetFiltergraph(graphBuilder);

I get a memory leak of around 10k every time around the
loop. This is not the 1M leak I get with the full
application, but it seems to indicate that some objects
are not being released... and in the full application,
those objects may be holding more objects in memory.

Is this a known problem? Is there a way for me to shutdown
the ICaptureGraphBuilder2 object cleanly? Calling
capGraph.SetFiltergraph(null) returns an error and does
not cure the leak. Should I not be trying to create all
the objects each time round the loop? Though I want to
release the webcam between snapshots.

Any help appreciated.

Thanks

Piers Lawson

The March Hare (MVP)

unread,
Oct 22, 2003, 9:07:23 PM10/22/03
to
This question is more appropriate for the ../managed group.


Piers Lawson

unread,
Oct 23, 2003, 3:02:22 AM10/23/03
to
>This question is more appropriate for the ../managed
group.

Thanks for your reply, however, I didn't think the other
group was appropriate, since the managed classes don't
cover DirectShow yet. I don't think my problem is related
to the fact I'm wrapping DirectX in a C# wrapper.

The problem appears to be with the way the object that
implements ICaptureGraphBuilder2 does not clean up
correctly (or I don't clean it up correctly) after
SetFiltergraph has been called.

I'm pretty confident the same problem would happen in an
unmanaged application. But if you still think the other
group is more appropriate, let me know and I'll post there.

Thanks

Piers

Xin Huang [MSFT]

unread,
Oct 23, 2003, 4:40:39 AM10/23/03
to
Usually the first step to troubleshooting a .NET application memory leak is
to check whether it is a managed leak or unmanaged leak. Use Perfmon and
monitor both Process / Private Byte and .NET CLR Memory / # Bytes in all
Heaps on the process. Do they both grow continuously, or only private byte
grows?

If it is a managed leak, probably someone is holding all the objects so GC
can't release them. You can use the Allocation Profilter from
www.GotDotNet.com to troubleshoot.

If it is an unmanaged leak, you may check if some COM objects are not
released, or if some CoTaskMemory is not freed. Then you may write an
equivalent C++ sample to test if it is the DShow components / filters are
leaking.

Hope this helps.

Regards,
Xin

This posting is provided "AS IS" with no warranties, and confers no rights.

Are you secure? Visit http://windowsupdate.microsoft.com to get the latest
critical updates and service packs available for your computer's Windows
operating system.

Piers Lawson

unread,
Oct 23, 2003, 8:00:56 AM10/23/03
to
Thanks Xin

I followed your suggestion. The private bytes is climbing,
whereas the .Net memory is flat.

I'm fairly sure it is DirectShow that is leaking as the
only difference between the non-leaking code and the
leaking code is the introduction of:

capGraph.SetFiltergraph(graphBuilder);

Which suggests to me that calling SetFiltergraph sets up
some circular references. How should I tear them down?

>If it is an unmanaged leak, you may check if some COM
>objects are not released

All the calls to Marshal.ReleaseComObject return 0,
indicating that the runtime callable wrapper has been
released and hence my app has released the underlying COM
objects. Also the memory leak is only there if I call
SetFiltergraph().

>or if some CoTaskMemory is not freed.

The only method I'm calling is SetFiltergraph which
doesn't return any allocated memory that I should free.

Piers

Piers Lawson

unread,
Oct 24, 2003, 12:07:26 PM10/24/03
to
Apologies to you both. The error turned out to be a double
increment of the reference count when using
Marshall.QueryInterface.

Piers

0 new messages