如何解决私有字节(本机内存)泄漏?

9
我正在开发一个C#应用程序,似乎存在内存泄漏问题。我已经使用内存分析器,并发现我的私有字节不断增加,但是所有堆中的字节没有增加,这意味着可能存在本地内存泄漏问题。现在我被卡住了,如何找到本地代码中的内存泄漏?

你知道漏洞在哪里吗?如果没有代码我们无法帮助你... - Karel Frajták
你不会在C#中编写本地代码。当然,你唯一能做的就是确保你正确处理了Interop。 - Rudi Visser
1
这是性能分析器常见的问题,它们会告诉你比你想知道的更多。增长的私有字节并不罕见,它需要一段时间才能稳定下来。你是否真的遇到了OutOfMemory异常?如果没有,那么请将此忽略。 - Hans Passant
@Karel Frajtak - 如果我告诉你这段代码是谷歌的下一个引擎,你会让我保密吗? - Erez
从谷歌上无意中发现了这个,想知道我是否正在使用 Erez 处理的存在内存泄漏的谷歌下一代引擎。 - Code Monkey
5个回答

4

首先,如果您有一个泄漏进程的转储文件,您可以在WinDbg中打开它并发出以下命令:

!address -summary

  • 如果RegionUsageHeap很大,则应该是本机内存泄漏
  • 如果RegionUsageIsVAD,则应该是.NET内存泄漏。

如果这是本机泄漏,则您有两个选择:

  • 使用DebugDiag:当提示时,选择“本地内存泄漏和句柄泄漏”,选择要诊断的进程,并开始使用应用程序,直到您遇到内存泄漏。完成后,生成应用程序的完整转储(右键单击泄漏规则并选择完整用户转储)。然后,您可以分析生成的转储(需要正确配置符号才能有效工作):在“高级分析”选项卡上,选择“内存压力分析器”,打开转储文件并按“开始分析”。这将生成一个HTML报告,您可以进行分析。您可以参考此页面以获取详细步骤。

  • 使用Application Verifier / WinDbg。在应用程序验证器中,选择您的应用程序(.exe)。在测试页面上,请确保选择了基础/堆。在下面的窗格中,请确保“跟踪”设置为true。一旦保存了配置,重新运行应用程序,并在发生泄漏时生成完整的转储。不要忘记在生成转储后清除应用程序标志。然后,您可以从WinDbg中打开转储,并使用“!heap”命令调查泄漏。特别是,“!heap -l”将给您一个泄漏块的列表,“!heap -p -a ”将显示块的详细信息,包括分配的调用堆栈。

如果这是.NET泄漏,有第三方工具可以进行故障排除。从1.2版本开始,DebugDiag也可以执行.NET内存泄漏分析(但我从未尝试过这个功能)。

3

在托管应用程序中诊断本机内存泄漏(至少最初)与诊断任何其他本机应用程序中的内存泄漏非常相似。

我通常解决这些问题的方式是让进程泄漏大量内存,获取完整的进程转储,然后检查转储以查看使用最多内存的内容。例如,如果您的进程具有正常/初始私有字节约为20MB,但您可以使进程泄漏内存直到它具有约200MB的私有字节,则很有可能其中约180MB的内存已经泄漏 - 一般来说,分配最多内存的内容是您应开始查找的地方。

Microsoft有一个非常有用的工具称为DebugDiag - 最初是为诊断IIS中的内存泄漏而开发的,它是一个非常多才多艺的工具,在处理内存问题时非常方便。如果您提供崩溃转储,它将执行一些分析并且至少应该告诉您哪个模块分配了所有那些内存,然后您可以更具体地查看该模块的使用方式。


0
很难在没有更多信息的情况下给出确定性的回应,但似乎你尝试使用的库存在内存泄漏问题。根据它所编写的语言,你需要使用适当的工具来检测该库。如果你没有该库的源代码,请联系开发人员修复泄漏问题。
如果您可以发布库的名称和一些源代码(以及本机方法签名),我们可能能够给您一些更具体的建议。

0

由 .NET Framework 管理的堆中的私有字节,您需要使用专业工具来分析您的源代码。例如使用 Red Gate Memory Profiler,查找已创建但未被处理的对象。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接