如何以可靠和自动的方式测量.NET中的内存泄漏?

时间:2009-02-10 09:52:49

标签: .net memory-leaks

我编写了一个自动化测试,以确保我们的应用程序不会泄漏(托管和非托管内存),现在和随后的开发成长。问题是我的测试似乎不可靠,但我不知道这是否是.NET和泄漏定义或测试所固有的。

就是这样:

 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;
        }
    }

我的问题是:为什么我的差异变化很大? (例如:一次运行给出11Mo,下一次给出33 Mo)。这些变化是正常的还是可以删除它们?

精确度:我不是在寻找一个分析工具! (我已经使用了一个!)

5 个答案:

答案 0 :(得分:3)

您可以尝试使用外部探查器,它们可以用于查找应用程序中的内存泄漏和瓶颈。依赖于垃圾收集器调用和打印值不是使用分析器的准确广告。 .NET有许多可以在Google上搜索它们。只是引用一些:

来自Microsoft official one

给他人

Yourkit

MemProfiler

JetBrains

答案 1 :(得分:2)

PrivateBytes是进程的内存占用量。对于托管代码,您只在托管堆上分配空间。但是,操作系统对托管堆一无所知。对于Windows,.NET应用程序只是另一个过程。

但是,进程本身显然需要托管堆的内存。即运行时将使用标准OS调用分配内存段。如果可能,这些段将被重用,并且可能不一定在垃圾收集后释放。

答案 2 :(得分:2)

使用GC.GetTotalMemory()获取当前在托管堆上分配的估计字节数。

对于真正的内存泄漏检测,我建议你转向一个特殊的分析器。

答案 3 :(得分:0)

你会发现内存泄漏本身只在你的P / Invoke代码中。 .Net中的“新”内存泄漏是死引用。 .Net中出现泄漏的大多数内存问题实际上都涉及保存对不再使用的对象的引用,这意味着它永远不会被垃圾回收。

请注意线程,我会警惕你到达可以可靠地调用你指定的函数的点,并保证所有对象现在都超出了范围。

答案 4 :(得分:0)

我最近发现了这个用于捕获异常的工具,它只是在beta中测试并且只能在XP中使用。 您可以使用它来了解应用程序的运行方式。阅读包装说明:

ExcpHook ver 0.0.5-rc2

和此:

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