【问题标题】:Memory Leak in .net application + strange GC behavior.net 应用程序中的内存泄漏 + 奇怪的 GC 行为
【发布时间】:2013-05-03 08:25:16
【问题描述】:

我不完全确定该去哪里寻求帮助,所以我想我会尝试使用 stackoverflow,因为它通常可以回答大约 90% 的与编程相关的问题。

简而言之,我有一个正在泄漏内存的开源 .NET 应用程序。从某种意义上说,这可能不是真正的内存泄漏,当应用程序关闭时,我怀疑内存已被回收,但在它运行时,它会不断分配更多内存而不释放它。最终,System.OutOfMemoryException 被抛出。

为了调试问题,我按照this article 中推荐的步骤进行了操作,并生成了下图,其中红色是 .NET/CLR 内存“所有堆中的#Bytes”,绿色是带有 windows 的进程“私有字节” ' 性能监视器工具(请注意,绿线已被统一缩小以显示更接近红线,因为我只关心线条的形状):Performance Monitor Output。

我将图像作为托管内存泄漏的证据,然后使用 Windows 的调试诊断工具尝试定位泄漏源(如文章中所述)。但是我从调试诊断工具得到的报告很奇特。

基本上,我在应用程序运行时每 5 秒尝试一次收集“完整用户转储”的每次尝试都被垃圾收集器始终处于当时的垃圾回收周期,导致调试诊断工具输出错误,并阻止它收集任何有用的 .NET 内存相关信息。

现在我被卡住了,我知道我有一个托管内存泄漏,但我不知道如何缩小它的范围。我也很困惑垃圾收集器如何总是处于收集周期的中间,这让我想知道垃圾收集线程是否被某种方式阻塞,阻止它释放内存和/或退出垃圾收集周期。

在性能监视器图的某些部分中,分配的 .NET 内存稍微下降了一点,因此垃圾收集器不会永远卡住,但它肯定在大部分时间都卡住了,否则应该是调试诊断能够做一个用户转储。

几个问题:

  1. .NET 应用程序中的垃圾收集器是否有可能在尝试释放一些内存时卡住,可能来自一些编码不良的析构函数/终结器或其他什么?

  2. 我可以使用什么策略来继续缩小问题的根源?

【问题讨论】:

    标签: .net memory-leaks debugdiag performance-monitor


    【解决方案1】:

    如果您提供 .NET Framework 版本、操作系统版本、您的进程位数和计算机上的处理器数量,将会有所帮助。如果您很快收到内存不足异常,我会认为您正在运行 32 位进程,但如果您能确认,仍然会有所帮助。

    首先,您应该通过查找进程的 %Time in GC 内存计数器来真正检查 GC 是否确实是问题的原因。您可以在 .NET CLR Memory 对象下的 PERFMON 中对此进行监控。如果这个计数器大于 30%,那么你肯定有 GC 问题。您粘贴的 PNG 并没有告诉我每秒分配了多少内存,所以如果它很高,那么 GC 会启动更多。

    需要注意的一点是使用最新的调试诊断工具来分析转储,看看您是否看到了不同的东西。 DebugDiag 1.2 中存在一个问题,它可能导致错误地报告“垃圾收集中间”消息,因此您要确保 GC 在转储时确实在运行。您可以从 @ 下载最新版本987654321@ 并使用该工具分析相同的转储文件,看看是否报告了不同的内容。同时在您的报告中搜索 GarbageCollectionGeneration 字符串,这将向您显示负责调用 GC 的线程。查看该线程的堆栈,您可能能够确定该线程正在做什么,最终调用了 GC。这可能有帮助,也可能没有帮助。

    回答您的其他问题:-

    1) 如果任何线程禁用了 PRE-EMPTIVE GC,GC 可能会卡住。您可以阅读文章http://blogs.msdn.com/b/tess/archive/2008/02/11/hang-caused-by-gc-xml-deadlock.aspx 更多地了解 PRE-EMPTIVE GC 以及如何找出禁用了抢先式 GC 的线程。

    2) 我会在 WinDBG 中打开转储,然后按照上面博客中提到的方法查看是否到达某个地方。如果框架是 .net 框架 4.0 或更高版本,您还可以使用 PERFVIEW 工具收集跟踪信息,并提供有关 GC 发生原因的良好信息。在http://channel9.msdn.com/Series/PerfView-Tutorial/PerfView-Tutorial-9-NET-Memory-Investigation-Basics-of-GC-Heap-Snapshots 观看 PERFVIEW 的视频以解决 GC 问题

    此外,如果这个 EXE 正在做一些后台处理,您可能需要启用 GC 的服务器模式,看看是否有帮助。阅读文章http://blogs.msdn.com/b/clyon/archive/2004/09/08/226981.aspx 了解更多信息。

    希望对你有帮助!!!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-06
      • 2015-05-09
      • 2021-03-28
      • 2020-12-19
      • 2011-04-01
      • 2012-03-07
      相关资源
      最近更新 更多