.NET应用程序突然出现非托管内存的极端增长

时间:2011-10-12 18:47:35

标签: c# wcf sockets memory-leaks unmanaged-memory

我正在运行一个展示一些非常特殊问题的应用程序。它运行良好约2.5小时,然后突然无管理的内存开始增长,并迅速增长。在大约半个小时左右的时间内,应用程序崩溃了。

应用程序未使用任何非托管DLL。它正在与外部应用程序通信。它使用套接字(通过Stream使用)和通过WCF流​​进行读取。

我用ANTS描述了它。非托管内存利用率的突然变化非常惊人;它永远保持完全平坦,然后突然开始上升并继续以稳定的速度这样做,直到应用程序失败。托管内存中的任何内容似乎都不合适。

鉴于我并非故意使用非托管代码,因此很难确定漏洞的来源。 ANTS没有帮助。当问题从一开始就没有稳定增长时就很难清除代码(应用程序一直处于空闲状态,尽管它通过套接字以非常小的数据每秒对它进行一次ping服务器)。

要重新迭代,应用程序和服务器在此期间都处于空闲状态;这是在一个独立的测试系统(服务器和客户端)上运行。客户端是泄漏的客户。

2 个答案:

答案 0 :(得分:3)

您可能希望使用DebugDiag来监视内存泄漏,并提供有关分配内容,调用内容以及调用堆栈的信息。简而言之:

在流程开始(或重新启动)后不久,请执行以下操作:

  1. 打开DebugDiag。
  2. 取消向导。
  3. 转到“流程”标签。
  4. 右键单击所需的流程。
  5. 选择Monitor for Leaks。
  6. 单击“确定”。
  7. 在该过程运行一段时间后,内存问题显而易见:

    1. 转到DebugDiag
    2. 如果它仍未打开,请退出向导。
    3. 转到“流程”标签。
    4. 右键单击与第1部分相同的过程。
    5. 选择Create Full Userdump。
    6. 记下转储的位置。
    7. 此外,如果在捕获内存转储之前重新启动进程,则必须重新启用泄漏监视。

      获得转储后:

      1. 转到DebugDiag。
      2. 转到“高级分析”标签。
      3. 在顶部选择“MemoryAnalysis.asp”脚本。
      4. 点击底部的“添加数据文件”,然后选择之前创建的转储。
      5. 点击“开始分析”并查看结果。
      6. 获得该信息后,您应该能够确定内存分配的来源,并希望找到问题的原因。

        您可以从以下资源中找到更多信息:

答案 1 :(得分:0)

我们最终发现了这个问题。原来我们在两者之间有一个套接字连接,并且在空闲阶段我们发送一个KeepAlive数据包以防止监听器自动断开连接。但是,在闲置一段时间之后,通过WCF的一些特殊超时,套接字正在关闭服务器端。

所以基本上每次DispatchTimer都被触发时,keep-alive数据包会被写入套接字,但显然会阻塞。这不会阻止下一个DispatchTimer做同样的事情。虽然它看起来像是更大的东西,但是那些小数据包正在快速建立并占用所有非托管内存,我假设套接字的缓冲区(我相信我们使用NetworkStream进行连接)。随着逻辑的一些转变,问题就消失了。

感谢所有的投入,非常感谢!