我们有一个 .NET 2.0 应用程序,它是一项服务,主要通过 .NET 远程处理连接多个客户端。该服务在生产期间在客户端站点因OutOfMemory 异常而崩溃,因此目前他们被迫每天左右重新启动它以避免意外崩溃。
以前,我已经成功解决了托管代码中的几个内存泄漏案例(静态集合未清理保存在其中的对象,以及另一个逻辑线程数不断增加的案例)。所以我非常熟悉捕获内存转储并使用 WinDbg + SOS 搜索它们。
然而,在这种情况下,私有字节正在上升,而所有堆上的字节保持稳定,这表明非托管代码内存泄漏。我收到了带有实际 OOM 异常的故障转储,这使得它更加明显:
查看 Tess Ferandez 的关于处理 .NET 应用程序中非托管代码泄漏的博客以及网络上的其他一些资源,我排除了诸如大量动态程序集、常见XmlSerializer问题或3rd 方本机 DLL等问题(有没有)。但是,周围有很多P/Invokes。继续前进,检查堆返回给我以下信息:
第二个命令也返回了所有条目。现在,根据我读到的一些东西,我应该运行 !heap -p -a 来获取堆栈,但我得到的只是
根据这个问题,这是不正确的 gflags 使用等。但是,在本地启动服务并在其上附加调试器,目前不是一种选择。长话短说,我必须设置一个具有与客户端类似的配置和负载的环境才能完成它,但这还没有准备好。
所以,我很困惑。我不知道从哪里开始,或者即使我使用正确的方法来解决该问题。任何指针都非常受欢迎。
编辑#1:使用外部资源的线程上的 Thread.abort。具体来说,数据库连接通过 Oracle 的 ODP.NET 提供程序。这可能是本机堆泄漏的原因吗?