针对.NET生产服务中的内存泄漏

时间:2012-03-09 16:42:23

标签: c# .net tcp

我有一个在生产中运行的C#.NET服务。该服务用作客户端注册和发出请求的TCP服务器。在查看任务管理器时,它似乎泄漏了大约10MB /天。我似乎没有注意到这些(也许是因为流量和客户活动少得多)。在搜索时我已经读到任务管理器可能严重错误,但我不确定这是多么准确或在什么情况下TM会显示不正确的信息。

要解决这个问题,我需要更密切地监控内存消耗。问题是泄漏似乎只出现在生产中,其中部署的服务是为Release构建的。此外,因为它是一个无法直接运行的服务,带有附加的分析器/调试,我不知道如何用比TM更精确的东西来确定问题。

非常感谢任何团队的智慧,谢谢。

编辑:

  • 我已经为服务的私有字节添加了perfmon计数器(7MB开始)以及所有堆中的CLR内存(30MB开始)
  • 任务管理员说总内存大约为37MB,所以这似乎有意义
  • 第一部分是让服务去一天,然后再次检查我的柜台。

如果我的私有字节变得很大但CLR内存大概是静态的,则表示存在非托管泄漏。如果两者都变得巨大,那么这是一个可控的泄漏。

谢谢你们。

4 个答案:

答案 0 :(得分:4)

您的第一项任务是确定进程是否泄漏内存。您可以使用perfmon测量Private Bytes来完成此操作 http://www.goldstarsoftware.com/papers/CapturingVirtualBytesToALogFile.pdf

如果图表一直在上升(例如半小时),则会出现内存泄漏。然后,您可以使用其他计数器来确定这是否是.NET泄漏(.NET内存),尽管这不太可能。我发现在大多数情况下,有一个COM组件正在被调用但未被释放。

如果你确实有内存泄漏(这不仅仅是可变内存使用) - 运行一段时间后,进程将因内存不足而关闭。

答案 1 :(得分:2)

您需要以下MemoryProfilers之一才能对其进行监控;

http://www.jetbrains.com/profiler/

http://www.red-gate.com/products/dotnet-development/ants-memory-profiler/

还有其他选择,但这些选择非常强大,您可以使用它们分析远程应用程序的内存(至少JetBrains的解决方案处理它)

答案 2 :(得分:2)

请遵循以下指南:http://blogs.msdn.com/b/tess/archive/2008/03/25/net-debugging-demos-lab-7-memory-leak.aspx

它完全超出了你所描述的内容,即生产中的内存泄漏。如前所述,您必须首先确定它是使用perfmon和Private Bytes泄漏的非托管代码还是托管代码。

一般情况下,确保使用语句包装它们的网络对象,以便妥善处理它们。

我经常用于托管内存泄漏的工作流是在测试计算机上启动服务器,使用已知数量的连接(例如123,456个连接)命中它。然后通过转到任务管理器并右键单击进程名称并选择“create dump”来获取内存快照。使用WinDBG和SOS打开此转储并运行命令!dumpheap -stat。查找具有123,456个实例的多个对象。这些物体是否仍然在记忆中?如果没有在这些对象的实例上运行!gcroot来查找它仍在内存中的原因。

答案 3 :(得分:2)

  1. 使用任务管理器右键单击进程并选择创建转储文件,在内存处于泄漏状态时获取内存转储。您还可以使用ProcDump为您提供更多选项。

  2. WinDebug或Visual Studio中使用SOS Extensions检查内存。