如何在基于 C# 的复杂 Windows 服务中找到内存使用率高的原因?

Posted

技术标签:

【中文标题】如何在基于 C# 的复杂 Windows 服务中找到内存使用率高的原因?【英文标题】:How to find cause of high memory usage in a complex C# based Windows service? 【发布时间】:2022-01-14 23:13:32 【问题描述】:

我在找出复杂的基于 C# 的 Windows 服务中的内存问题的根源时遇到问题。不幸的是,问题并非一直发生,我仍然不完全知道导致它发生的条件。有时,当我检查服务使用的系统资源时,它会占用数 GB 的内存,直到它到处抛出 OutOfMemory 异常,因为没有任何剩余内存。

我有一个付费版本的 .NET Memory Profiler 可用,但到目前为止它一直没用,因为当服务使用过多内存时整个系统变得缓慢且不稳定,因此我无法将内存分析器附加到应用程序。

应用程序的解决方案由30多个单独的项目和数十万行代码组成,因此我无法仅通过查看源代码来找到问题的根源。

到目前为止,我唯一能做的就是在进程使用大量内存时为其创建内存转储(.dmp 文件)。有没有办法分析这个转储或其他任何可以帮助我缩小问题根源的方法?

【问题讨论】:

.dmp 文件可以在 Visual Studio 中进行分析。这就像调试过程一样。但它并没有真正显示内存的使用位置,但也许你可以得到进程在做什么的提示。您可以尝试增加日志记录,尤其是在可能使用大量内存的情况下(例如记录可疑列表的元素计数等)。 我希望大多数内存分析器能够导入转储文件以供进一步研究。所以我会检查你的分析器的文档。 【参考方案1】:

如果您可以在遗留项目的主要类中识别出一些中心方法,并且您已经有了某种日志记录,则可以通过调用

Process.GetCurrentProcess().PrivateMemorySize64

如果内存问题是“分散的”,至少这会给你一种感觉,例如。 G。如果内存问题仅发生在某些用例中(内存消耗跳跃,如果发生某些操作),则不释放对象进行垃圾收集等。然后你可以通过更多的日志记录和调查相应的代码部分来确定它。它很乏味,但是当您不能像您所说的那样使用代码检测时,我发现它很有效。如果你想通过内存转储来分析一个特定的情况,你可以使用 WinDbg 来分析它,但是第一次学习需要一些努力,并且将是一个单独的主题(参见https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-download-tools)。

【讨论】:

以上是关于如何在基于 C# 的复杂 Windows 服务中找到内存使用率高的原因?的主要内容,如果未能解决你的问题,请参考以下文章

如何在基于 C# 的 Windows 服务中处理以不同时间间隔并行运行的多个任务?

c#计时器如何保存计时

如何在 C# windows 服务中使用 Git 标签号代替 SVN 版本号

在 c# (linux) 中找不到 PrivateFontCollection 错误

C#创建Windows Service(Windows 服务)基础教程

C#创建Windows Service(Windows 服务)基础教程