2

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

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

然而,在这种情况下,私有字节正在上升,而所有堆上的字节保持稳定,这表明非托管代码内存泄漏。我收到了带有实际 OOM 异常的故障转储,这使得它更加明显:

!address -摘要

查看 Tess Ferandez 的关于处理 .NET 应用程序中非托管代码泄漏的博客以及网络上的其他一些资源,我排除了诸如大量动态程序集、常见XmlSerializer问题或3rd 方本机 DLL等问题(有没有)。但是,周围有很多P/Invokes。继续前进,检查堆返回给我以下信息:

堆

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

这个

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

所以,我很困惑。我不知道从哪里开始,或者即使我使用正确的方法来解决该问题。任何指针都非常受欢迎。

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

4

1 回答 1

2

但是,周围有很多 P/Invokes

编辑#1:使用外部资源的线程上的 Thread.abort

这只是出现这种问题的完美风暴。它们中的任何一个都足以单独导致不受控制的内存泄漏。在你的开发机器上看起来一切都是花花公子。但它肯定不是在执行真机正在处理的那种数据负载。

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

如果您仍然遇到问题,那么您需要 gflags.exe 和 umdh.exe 等工具,这些工具可在 Windows 调试工具中找到。现在是 SDK 的一部分。最后的手段,它们只适用于调试符号,而甲骨文并不是那种让这变得容易的公司。他们的生态系统对“我会解决你的问题”的高薪顾问很友好。如果您找到合适的,这也可以解决。

于 2012-05-13T21:17:59.677 回答