你能重现这个64位.NET 4 GC bug吗?

17

更新:微软已经重现了这个bug,并正在修复中。

在评估.NET平台用于低延迟软件开发的可行性时,我们发现了一个严重的问题,即.NET 4并发工作站垃圾收集器中存在一个bug,可能会导致应用程序暂停数分钟。

在我们的三台计算机上,以下简单的C#程序会导致GC泄漏内存,直到没有剩余内存,然后启动一次大型GC周期,导致程序暂停数分钟,同时回收11GB堆内存:

    static void Main(string[] args)
    {
        var q = new System.Collections.Generic.Queue<System.Object>();
        while (true)
        {
            q.Enqueue(0);
            if (q.Count > 1000000)
                q.Dequeue();
        }
    }
在64位Windows操作系统上,您需要使用.NET 4编译为x64,并使用默认(并发工作站)GC以及默认的(交互式)延迟设置来运行。

以下是在此计算机上运行此程序时任务管理器的截图:

alt text

请注意,在这里泄漏了11GB的堆内存,而这个程序所需的内存不超过100MB。

我们现在已经积累了大约十几个F#和C#的可复现此错误的示例,看起来它与GC写入屏障中的一个错误有关,当大多数gen0幸存时就会出现。 然而,微软尚未能够再现此问题。您能吗?如果可以,请尽可能准确地描述您的设置,以便我们可以尝试缩小确切需要出现此错误的条件范围。


@Jon Harrop:我并没有发现它很灾难性。我看到的是更少的垃圾回收,约占10%。但这并没有影响性能(基于IronScheme和.NET 3.5的测试结果)。 - leppie
1
恭喜你终于将这个问题归类为正式的bug。 - alex
请问您能否提供微软的错误报告链接?这个问题是否已经解决了? - Mary Ellen Bench
1
@MaryEllenBench:错误已经修复。我不知道错误报告在哪里。我刚刚写信给微软的Maoni Stephens,她立即解决了它。 - J D
它在哪个.NET版本中修复了? - Mary Ellen Bench
显示剩余7条评论
2个回答

3

我无法重现它。我在拥有4GB内存的x64上进行了尝试,并编译成ANY格式。最大的内存使用量约为2.5GB。最大GC暂停时间约为1084毫秒。

这是我的GC ETW统计输出。

alt text

您也可以按时间获取GC事件。

alt text

可能您运行时类似的跟踪输出可以帮助您更好地了解底层发生了什么。

在.NET 4.0中,有一个称为Windows事件跟踪(ETW)的功能,提供框架跟踪信息。以下是特定于GC的信息。

GC

而要获取这些信息,有一个名为PerfView的工具。

PerfView

以下是使用该工具获取GC信息的步骤:

  1. 以管理员身份启动cmd.exe,这需要收集ETW跟踪。
  2. 启动要跟踪的应用程序。
  3. 发出命令“PerfMonitor.exe /process:4180 start”,其中4180是进程ID。
  4. 让应用程序运行一段时间。
  5. 然后发出“PerfMonitor.exe stop”命令。
  6. 获取报告的命令为“PerfMonitor.exe GCTime”。这将生成一个报告,并在浏览器中打开带有GC统计信息的报告。

1
感谢提供 PerfMonitor 的参考。根据该工具,最长暂停时间仅为618毫秒,但更仔细的检查显示每60-130毫秒会有常规的18毫秒暂停,除了在最长的618毫秒GC暂停之前立即出现了一个145秒的巨大间隙。因此,我的时间并没有浪费在 PerfMonitor 认为的GC暂停上。 - J D
微软的Maoni Stephens和这个垃圾收集器的作者说:“这是一次GC暂停。PerfMonitor没有解释足够的信息来识别它。”。 - J D

2
在linqpad中运行代码,如果以64位运行会导致内存消耗巨大; 以32位运行则正常。我的电脑是Windows 7 x64旗舰版,安装了VS.NET和其他开发工具,可能存在一些在空白机器上不存在的奇怪的调试器钩子。奇怪的是他们没有重现这个问题。你确定没有沟通问题吗?另外,使用“new object()”而不是装箱值类型会导致相同的问题(并不令人惊讶),因此您可能需要从您的重现案例中删除装箱的混淆因素。

谢谢!“你确定那里没有沟通问题吗?” 可能有。我已经将重现作为C#解决方案交给了微软的其他人进行测试。“你可能想要消除混淆因素。”好主意,我会这样做的。 - J D

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接