.net - .NET 应用程序中与 native 堆相关的内存泄漏

标签 .net memory-leaks out-of-memory unmanaged-memory

我们有一个 .NET 2.0 应用程序,它是一个服务,多个客户端主要通过 .NET 远程处理连接。该服务在生产过程中在客户端站点因 OutOfMemory 异常而崩溃,因此目前他们被迫每天左右重新启动一次以避免意外崩溃。

以前,我已经成功解决了托管代码中的几种内存泄漏情况(静态集合未清理其中保存的对象,以及逻辑线程数不断增加的另一种情况)。因此,我非常熟悉捕获内存转储并使用 WinDbg + SOS 搜索它们。

然而,在这种情况下,私有(private)字节不断增加,而所有堆上的字节保持稳定,这表明非托管代码内存泄漏。我收到了包含实际 OOM 异常的故障转储,这使其更加明显:

!address -summary

检查了 Tess Ferandez 的有关处理 .NET 应用程序中非托管代码泄漏的博客以及网络上的其他一些资源,我排除了诸如大量动态程序集之类的问题,这是一种常见的问题XmlSerializer 问题,或第 3 方 native DLL(没有)。然而,周围有大量的P/Invokes。接下来,检查堆返回给我以下内容:

heaps

第二个命令也返回所有条目。现在,根据我读到的一些内容,我应该运行 !heap -p -a 来获取堆栈,但我得到的只是

this

根据this question是不正确的 gflags 使用等。但是,当前可以在本地启动服务并在其上附加调试器。长话短说,我必须设置一个具有与客户端类似的配置和负载的环境才能完成它,而这还没有准备好。

所以,我陷入了困境。我不知道从这里继续哪里,或者即使我使用正确的方法来解决该问题。非常欢迎任何指点。

编辑 #1: 在使用外部资源的线程上进行 Thread.abort。具体来说,通过 Oracle 的 ODP.NET 提供程序进行数据库连接。这可能是 native 堆泄漏的原因吗?

最佳答案

However, there is a good number of P/Invokes around

Edit #1: Thread.abort on threads that use external resource

遇到这种问题简直就是一场完美的 Storm 。如果它们中的任何一个都足以单独导致不受控制的内存泄漏。在你的开发机器上,一切看起来肯定都很顺利。但它肯定不会执行真实机器正在处理的数据负载类型。

您不会从工具中获得很多帮助,无论如何,不​​是 .NET 类型的帮助。绝对要从完全摆脱线程中止开始,这永远不会有好结果。您没有提供任何背景信息,因为您很难给出具体建议。一定要使用虚假的自动生成数据建立一个数据库,这样您就可以在舒适的小隔间中检查代码调整的结果。您需要大量数据,因为它泄漏的速度不够快。

如果您仍然遇到问题,那么您需要 gflags.exe 和 umdh.exe 等工具,这些工具可在 Windows 发行版的调试工具中找到。现在是 SDK 的一部分。最后的手段是,它们只能与调试符号配合使用,而 Oracle 并不是那种能够轻松做到这一点的公司。他们的生态系统对于把“我来解决你的问题”的高薪顾问放在一边很友好。如果您找到合适的人,这也可以解决问题。

关于.net - .NET 应用程序中与 native 堆相关的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10553034/

相关文章:

java - 读取和写入大图像

java - 如何分析Snap.*trc文件?

c# - 在 Umbraco 6 中构建联系表单

c# - 如何在同一个项目中针对netcoreapp2.0和net461

linux - Docker 容器上的 ImageMagick 生成格式错误的 PNG 图像

javascript - 运行 javascript 过夜后系统挂起

java - JNI 释放内存以避免内存泄漏

c++ - 在内存充足但碎片化的环境下,new/malloc 是否会造成内存洗牌?

.NET DBNull 与所有变量类型都没有?

.net - Visual Studio 中的哪个程序允许我查看 DLL 以查看其 API?