All Your Base Are Belong To Us

Mostly .NET internals and other kinds of gory details

Is It a Managed or a Native Memory Leak?

How do you determine whether the memory issue you seem to be experiencing is a .NET memory leak or a native memory leak?  Why is it even important?

It's the first question I as a consultant would ask you if we were to talk over the phone regarding a high-memory problem you've having.  It's extremely important because in most of the cases it narrows the scope of the problem and facilitates bringing the appropriate people, tools and resources for focusing on the task at hand.

The process for diagnosing a .NET memory leak revolves around tools such as the CLR Profiler, WinDbg, SOS.DLL and the useful set of commands such as !VMStat, !DumpHeap, !TraverseHeap, !GCRoot and others.  The process for diagnosing a native memory leak, on the other hand, is usually significantly more complicated and vague, consisting of analyzing the memory for patterns, searching strings in memory, attempting to correlate memory usage to modules, and so on.

So how do you tell?  The first step that you're definitely capable of taking in the right direction is opening Performance Monitor and looking at the values of two important performance counters for your application's process:

  • .NET CLR Memory / # Bytes in All Heaps
  • Process / Private Bytes

The private bytes counter for your process is the amount of memory committed to the process by the Windows memory manager.  It doesn't have to reside in physical memory - it might be paged out or in transition - but it does reflect the memory usage of your application.  Note the "private" in the counter's name - only memory that isn't shared with other processes on the system is considered for this counter's value.  Shared memory sections or loaded assemblies are not considered.

The .NET bytes in all heaps counter is the amount of managed memory allocated in your process (for all AppDomains).  This is garbage-collected memory, and a leak here indicates that we can use the standard arsenal for managed high-memory scenarios.

There can really be three distinct scenarios from this point on:

  1. The private bytes counter is climbing but the .NET bytes in all heaps counter remains constant.  This indicates a native memory leak.
  2. The private bytes counter and the .NET bytes in all heaps counter are climbing at the same rate (the difference between the two remains constant).  This indicates a managed memory leak.
  3. The private bytes counter and the .ET bytes in all heaps counter are climbing at different rates (the difference between the two is not constant).  This indicates a combined managed and native memory leak, e.g. leaking a managed component that holds a reference to a COM object (via an RCW) or creating a CCW/RCW cycle.

Let's take an example from one of my recent debugging consultations.  At the client's site I've set up a performance counters log to monitor the above two counters and determine what kind of leak we're talking about.  Here's what the graph looked like:

image

The black highlighted line is the managed memory counter, the blue line is the private bytes counter.

From this graph, it's evident that the applications is leaking managed memory only.  The difference between the two counters stays constant, meaning we're in leak category #2 above.  This enables a smooth transition to dump analysis for managed leaks.

Comments

Dew Drop - July 13, 2008 | Alvin Ashcraft's Morning Dew said:

Pingback from  Dew Drop - July 13, 2008 | Alvin Ashcraft's Morning Dew

# July 13, 2008 7:08 PM

Arjan`s World » LINKBLOG for July 14, 2008 said:

Pingback from  Arjan`s World    » LINKBLOG for July 14, 2008

# July 14, 2008 11:05 AM

Olivier said:

What about analysing a native memory leak in a .NET application ?. I have such a problem with a WCF 3.5 Service, and can't figure out what to do, because I'm not using any PInvoke/COM calls in this service.

# July 15, 2008 5:47 PM

AC said:

So what is the difference between a Native and a Managed memory leak?  What do you do if you have a Native Memory leak and the # of Bytes in all heaps doesn't change while private bytes grows out of control?  Where do I start looking? (Windows web server, .NET C# application on framework version 2.0 with SP 1)

# August 6, 2008 11:22 AM

Sasha Goldshtein said:

You have to start looking for unmanaged components running in your process, or for unmanaged memory allocations from your managed code (rare, but doable with APIs from the Marshal.Alloc... family).

There are helpful utilities such as DebugDiag that can give you a direction as to which module or allocation path seems to be leaking.

# August 9, 2008 5:57 AM

Recent URLs tagged Memoryleak - Urlrecorder said:

Pingback from  Recent URLs tagged Memoryleak - Urlrecorder

# April 16, 2009 11:31 AM
Leave a Comment

(required) 

(required) 

(optional)

(required) 


Enter the numbers above: