views:

355

answers:

5

I wrote an automated test in order to ensure that our application does not leak (managed & unmanaged memory) now AND later as development grows up. The problem is that my test does NOT seem reliable, but I don't know whether this is inherent to .NET and leak definition or to the test.

It happens this way:

 long start = PrivateBytes;
 // here is the code for an action which is expected to be memory-constant
 long difference= PrivateBytes-start;
 Console.WriteLine(difference); // or Assert(difference < MyLimit);


private static long PrivateBytes
    {
        get
        {                
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            return Process.GetCurrentProcess().PrivateMemorySize64;
        }
    }

My question is: why do I get huge variations in difference? (example: one run gives 11Mo, the next one 33 Mo). Are these variations normal or can I remove them?

Precision: I am NOT looking for a profiler tool! (I already use one!)

+3  A: 

You can try to use an external profiler, they're made right for your purpose to find memory leaks and bottlenecks in applications. Relying on Garbage Collector calls and print values is not as accurate ad using a profiler. There are many for .NET you can search Google for them. Just to cite some:

from Microsoft official one

to others

Yourkit

MemProfiler

JetBrains

Stefano Driussi
I've used the SciTech MemProfiler on a medium-sized app (500k lines), albeit three years ago, and it worked really well. You can capture snapshots, then "diff" the snapshots to find out what's actually changing.
stusmith
+2  A: 

PrivateBytes is the memory footprint of the process. For managed code you only allocate space on the managed heap. However, the OS doesn't know anything about the managed heap. To Windows a .NET application is just another process.

However, the process itself obviously needs memory for the managed heap. I.e. the runtime will allocate segments of memory using the standard OS calls. These segments are reused if possible and may not necessarily be released following a garbage collect.

Brian Rasmussen
A: 

You'll find that memory leaks themselves are only in your P/Invoke code. The "new" memory leak in .Net are dead references. Most memory issues in .Net that appear to be leaks are actually involved with holding a reference to an object that you are no longer using which means that it will never be garbage collected.

Beware of threads too, I would be wary of you reaching a point where you can reliably call that function you have specified and guarantee that all objects are now out of scope.

Spence
+2  A: 

Use GC.GetTotalMemory() to get the estimated amount of bytes currently allocated on the managed heap.

For real memory leak detection I suggest your turn to an special profiler.

Gerrie Schenck
A: 

I recently find this tool for catch exceptions, it is beta and wonk only in XP. You can use to get an idea of how an application is operating. Read instructions in package:

ExcpHook ver 0.0.5-rc2

and this :

Static Analysis Tools For .NET, Matt Berseth’s Blog

lsalamon