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

本文关键字:内存 泄漏 服务 NET 针对 | 更新日期: 2023-09-27 18:27:20

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

为了解决这个问题,我需要更密切地监控内存消耗。问题是,泄漏似乎只出现在生产中,部署的服务是为Release构建的。此外,由于这是一项不能直接作为带有探查器/调试的VS运行的服务,我不知道如何用比TM更精确的东西来最好地确定问题

任何团体智慧都将不胜感激,谢谢。

编辑:

  • 我为服务的privates字节添加了perfmon计数器(启动7MB),并在所有堆中添加了CLR内存(启动30MB)
  • 任务管理器说总内存约为37MB,所以这似乎是有道理的
  • 第一部分是让服务暂停一天,然后再次检查我的柜台

如果我的私有字节变大,但CLR内存大致是静态的,这将表明存在非托管泄漏。如果两者都变得巨大,那么这是一次有管理的泄漏。

谢谢大家。

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

您的第一个任务是确定进程是否正在泄漏内存。您可以通过perfmon测量私有字节来完成此操作http://www.goldstarsoftware.com/papers/CapturingVirtualBytesToALogFile.pdf

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

如果你真的有内存泄漏(这不仅仅是可变的内存使用),进程在运行一段时间后会因内存不足异常而关闭。

您需要以下MemoryProfiler之一来监视它;

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

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

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

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

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

一般来说,要确保对网络对象使用语句进行包装,以便正确处理它们。

我经常用于管理内存泄漏的工作流程是在测试机器上启动服务器,使用已知数量的连接(比如123456连接)。然后进入任务管理器,右键单击进程名称并选择"创建转储",获取内存快照。使用WinDBG和SOS打开此转储并运行命令!杜姆菲亚普-统计。查找具有多个123456实例的对象。这些对象应该还在内存中吗?如果不运行!对这些对象的实例执行gcroot操作,以找出它仍在内存中的原因。

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

  2. 在WinDebug或Visual Studio中使用SOS扩展来检查内存。