memory leak disappears when taking snapshot

Use this forum for questions on how to use .NET Memory Profiler and how to analyse memory usage.
Post Reply
JohannesFleck

memory leak disappears when taking snapshot

Post by JohannesFleck » Tue Jul 26, 2011 10:32 am

hi

I'm investigating a memory leak in a winforms c# 3.5 app. There is defintely a memory leak because objects are not released when closing a form.

But everytime I take a snapshot from the running app the otherwise held memory is released instantly and my memory leak is gone.

Now my questions is what could .net memory profile possible do to get the GC to collect the objects?
If I know that I that the same in my code :-)

rgds
Johannes

JohannesFleck
Posts: 5
Joined: Tue Jul 26, 2011 10:38 am

Re: memory leak disappears when taking snapshot

Post by JohannesFleck » Tue Jul 26, 2011 10:41 am

I've just registered with JohannesFleck so the above is my post...

Andreas Suurkuusk
Posts: 1028
Joined: Wed Mar 02, 2005 7:53 pm

Re: memory leak disappears when taking snapshot

Post by Andreas Suurkuusk » Tue Jul 26, 2011 9:30 pm

In what way are the instances not released when you close the form? Are you keeping a reference to them somehow?

When you collect a snapshot in the profiler, the profiler will issue a sequence similar to:

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();

This is done to avoid reporting false memory leaks, by making sure that as many instances as possible has been GCed.

You can also collect a gen #0 snapshot if you don't want to perform a heap cleanup when you collect the snapshot. A gen #0 snapshot will only perform a single gen #0 GC while collecting the snapshot.
Best regards,

Andreas Suurkuusk
SciTech Software AB

JohannesFleck
Posts: 5
Joined: Tue Jul 26, 2011 10:38 am

Re: memory leak disappears when taking snapshot

Post by JohannesFleck » Wed Jul 27, 2011 7:36 am

References are kept via Eventhandlers, Delegates
Its a very big complex application with plugin architecture, UserControls, MDI Windows, Caching for some instances but not others, Undo History etc...

What is your understanding of false memory leaks?
My memory leak doesn't go away even if I call GC.Collect several times (added a middle mouse click for testing), yet your app seems to be able to get rid of it.

I'm new to this kind of debugging so any help would be much appriciated.
thanks
Attachments
MemProfiler-Snapshot-Release.png
screenshot,how memleak is released
MemProfiler-Snapshot-Release.png (15.69 KiB) Viewed 10045 times

JohannesFleck
Posts: 5
Joined: Tue Jul 26, 2011 10:38 am

Re: memory leak disappears when taking snapshot

Post by JohannesFleck » Wed Jul 27, 2011 12:57 pm

Just as explanation for other user:

I have found the reason for this behaviour.
While .net memprofiler shows the .net total bytes (managed memory) I made the mistake to compare this to ProcessExplorer Stats "private bytes".

My app is leaking native memory as well as ".net" memory heap and this explains why I can see a drop in memory in .net mem profiler but didnt see this with process explorer.

thanks!

Andreas Suurkuusk
Posts: 1028
Joined: Wed Mar 02, 2005 7:53 pm

Re: memory leak disappears when taking snapshot

Post by Andreas Suurkuusk » Wed Jul 27, 2011 1:06 pm

Yes, you are correct. The managed total bytes value is not directly related to the private bytes value. However, the fact that the private bytes value doesn't decrease when the total bytes value does, doesn't necessarily indicate a native memory leak. Even if the managed memory usage has decreased, the .NET runtime will not return the allocated memory to the OS directly. Most likely this memory is going to be needed again, so it will be more efficient for the runtime to keep the allocated memory. The runtime will release memory to OS under some conditions, but the rules for when that is performed are internal and are likely to be modified between runtime versions.
Best regards,

Andreas Suurkuusk
SciTech Software AB

Rhom
Posts: 1
Joined: Mon Oct 17, 2011 6:54 am

Re: memory leak disappears when taking snapshot

Post by Rhom » Mon Oct 17, 2011 7:00 am

Andreas, is that what the profiler does when we click "Snapshot"? Does it return allocated (but not used) memory back to the OS?

I have the same symptoms as described above in the image. My memory usage "appears" to have a leak as the graph goes up and up (no matter how many time I call GC.Collect.
HOWEVER, when I click snapshot the graph plummets back to the baseline to reveal that there is no actual leak. As you posted above I am calling:
GC.Collect()
GC.WaitForPendingFinalizers()
GC.Collect()
but don't get the same results.

Andreas Suurkuusk
Posts: 1028
Joined: Wed Mar 02, 2005 7:53 pm

Re: memory leak disappears when taking snapshot

Post by Andreas Suurkuusk » Tue Oct 18, 2011 9:02 pm

I'm sorry for the delay.

Prior to version 4.0.111, the profiler performed a sequence similar to the sequence below when collecting a snapshot.

GC.Collect();
// Wait a fixed amount of time to wait for pending finalizers.
Thread.Sleep( for a short while, e.g. 100 ms );
GC.Collect();
// Finally, collect the snapshot during a last garbage collection.
GC.Collect();

In version 4.0.111 the sequence more closely resembles:
// Collect GC and remember finalizable instances
GC.Collect();
// Wait a fixed amount of time to wait for pending finalizers.
while( initial finalizable instances left and not time out )
{
Thread.Sleep( for a short while );
}
// Finally, collect the snapshot during a last garbage collection.
GC.Collect();

The profiler will not force the runtime to return memory to the OS, but the runtime might behave differently based on how the GC was initiated. However, if you perform GC.Collect, GC.WaitForPendingFinalizers, GC.Collect, I think you should see a behavior similar to when you collect a snapshot.

Have you looked at the real-time graph when you call GC.Collect from your application? What happens to the live bytes and total bytes values?
Best regards,

Andreas Suurkuusk
SciTech Software AB

Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 22 guests