如何解决私有字节(本机内存)泄漏?
我正在开发一个 C# 应用程序,该应用程序似乎存在泄漏。 我使用了内存分析器,发现我的
私有字节不断增加,但所有堆中的字节没有增加,这意味着可能是本机内存泄漏
现在我陷入困境,如何查找本机代码中的内存泄漏?
I'm developing a C# application which seems to have a leak.
I've used memory profiler and found that my
private bytes keep increasing but Bytes in all Heaps do not, which means that probably it's a native memory leak
Now I'm stuck, how do I find memory leaks in native code ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
首先,如果您有泄漏进程的转储,您可以在 WinDbg 中打开它并发出命令:
!address -summary
如果这是本机泄漏,那么您有 2 个选择:
使用 DebugDiag:出现提示时,选择“本机内存泄漏和处理泄漏”,选择要诊断的进程,然后开始使用应用程序,直到您尝试内存泄漏。完成后,生成应用程序的完整转储(右键单击泄漏规则并选择完整用户转储)。然后,您可以分析生成的转储(您需要正确配置符号才能使其有效工作):在“高级分析”选项卡上,选择“内存压力分析器”,打开转储文件并按“开始分析”。这会生成您可以分析的 html 报告。您可以参考此页面了解详细演练。
使用应用程序验证器/WinDbg。在应用程序验证程序中,选择您的应用程序 (.exe)。在测试页面中,确保选择了 Basics/Heaps。在下部窗格中,确保“Traces”设置为 true。保存配置后,重新运行应用程序并在发生泄漏时生成完整转储。不要忘记在生成转储后清除应用程序标志。然后,您可以从 WinDbg 中打开转储,并借助“!heap”命令调查泄漏。特别是,“!heap -l”将为您提供泄漏块的列表,“!heap -p -a”将显示块的详细信息,包括分配的调用堆栈。
如果这是 .NET 泄漏,可以使用第三方工具对其进行故障排除。从版本 1.2 开始,DebugDiag 还可以执行 .NET 内存泄漏分析(但从未尝试过)。
First, if you have a dump of the leaking process, you can open it in WinDbg and issue the command :
!address -summary
If this is a native leak, then you have 2 options :
Use DebugDiag : when prompt, choose 'Native Memory leak and Handle leak', choose the process you want to diagnose, and start working with the application until you experiment the memory leak. When complete, generate a full dump of the application (right click on the leak rule and select Full user dump). You can then analyze the generated dump (you'll need to have the symbols properly configured for this to work efficiently) : on 'advanced analysis' tab, select 'Memory pressure analyzers', open the dump file and press 'Start analysis'. This produces and html report you can analyze. You can refer to this page for a detailed walkthrough.
Use Application Verifier / WinDbg. In application verifier, select your application (.exe). In tests page, be sure Basics/Heaps is selected. In the lower pane, be sure 'Traces' is set to true. Once the configuration saved, re-run the application and generate a full dump when the leak occurs. Don't forget to clean application flags after the dump is generated. Then you can open the dump from within WinDbg, and investigate the leak with the help of '!heap' command. In particular, '!heap -l' will give you a list of leaked blocks, '!heap -p -a ' will show the details of a block, including the call stack of allocation.
If this is a .NET leak, there are third party tools to troubleshoot it. Starting from version 1.2, DebugDiag is also enable to perform .NET memory leak analysis (never tried this however).
诊断托管应用程序中的本机内存泄漏(至少在最初)与诊断任何其他本机应用程序中的内存泄漏非常相似。
我通常处理这些问题的方法是让进程泄漏大量内存,进行完整的进程转储,然后检查转储以查看使用最多内存的进程。例如,如果您的进程有大约 20MB 的正常/初始私有字节,但您可以让进程泄漏内存,直到它有大约 200MB 的私有字节,那么很有可能会泄漏大约 180MB 的内存 - 一般来说分配最多内存的地方就是您应该开始寻找的地方。
Microsoft 有一个非常有用的工具,名为 DebugDiag -最初开发用于诊断 IIS 中的内存泄漏,它是一个非常通用的工具,在处理内存问题时非常方便。如果你给它一个故障转储,它会执行一些分析,并且应该(至少)告诉你哪个模块分配了所有内存,然后你可以开始更具体地查看该模块的使用方式。
Diagnosing native memory leaks in a managed application is (at least initially) very similar to diagnosing memory leaks in any other native application.
The way I normally approach these problems is to get the process to leak a large amount of memory, take a full process dump and then examine the dump to see what is using the most memory. For example if your process has a normal / initial private bytes of ~20MB but you can get your process to leak memory until it has ~200MB of private bytes, then there is a good chance that ~180MB of that memory is leaked - generally speaking whatever has the most memory allocated is where you should start looking.
Microsoft have a very useful tool called DebugDiag - initially developed for use in diagnosing memory leaks in IIS it is a very vesatile tool and very handy when dealing with memory issues. If you give it a crash dump it will perform some analysis and should (at the very least) tell you what module has allocated all of that memory, you can then start looking more specifically at how that module is used.
如果没有更多信息,很难给您可靠的答复,但听起来您尝试使用的库存在内存泄漏。您需要使用适当的工具来获取该库,具体取决于其编写的语言。如果您没有该库的源代码,请联系开发人员并让他们修复泄漏。
如果您可以发布库的名称和一些源代码(以及本机方法签名),我们也许可以为您提供一些更具体的建议。
It's hard to give you a solid response without more information, but it sounds like the lib you are trying to use has a memory leak. You'll need to the lib with the appropriate tools, depending on the language it was written in. If you don't have the lib's source, contact the developers and have them fix the leak.
If you can post the name of the library and some of your source code (as well as the native method signatures), we might be able to give you some more specific advice.
由.net框架管理的堆中的私有字节,您需要使用专业工具来分析您的源代码。例如使用红门内存分析器,查找已创建但未处置的对象。
private bytes in heaps managed by .net framework, you need use professional tool to analysis your source. such like use red gate memory profiler, find object created but not being disposed.
通常,使用 ANTS 内存查找内存泄漏时,我会得到最好的结果探查器。
(或其他工具,我个人在 ANTS 方面获得了最佳体验)
Usually I had the best results when hunting memory leaks using the ANTS Memory Profiler.
(Or other tools, personally I had best experiences with ANTS)