【发布时间】:2010-10-19 09:57:50
【问题描述】:
更新:Microsoft 现已重现该错误并正在努力修复。
在评估 .NET 平台在低延迟软件开发方面的可行性时,我们发现了 .NET 4 并发工作站垃圾收集器中的一个严重错误,该错误可能导致应用程序一次挂起长达几分钟。
在我们的三台机器上,以下简单的 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();
}
}
您需要在带有 .NET 4 的 64 位 Windows 操作系统上针对 x64 进行编译,并使用默认(交互式)延迟设置在默认(并发工作站)GC 下运行。
这是在这台机器上运行此程序时任务管理器的外观:
请注意,当此程序需要不超过 100Mb 的内存时,这里会泄漏 11Gb 的堆。
我们现在已经积累了大约十几个这个错误的重现,用 F# 和 C# 编写,它似乎与 GC 写入屏障中的一个错误有关,当大部分 gen0 幸存下来时。但是,微软尚未能够复制它。你可以吗?如果是这样,您能否尽可能准确地描述您的设置,以便我们可以尝试准确缩小此错误出现所需的条件。
【问题讨论】:
-
使用 serverGC 会发生什么?
-
.NET 内存性能计数器显示什么?
-
@leppie:使用其他 GC 选项或其他 GC(包括服务器)可以避免该错误。但是,并发工作站 GC 是 Microsoft 提供的稳定状态的唯一低延迟选项,我们想要低延迟。当然,服务器 GC 的延迟通常要差得多。微软对他们的 GC 算法很腼腆,但我相信服务器 GC 是天真的停止世界并行遍历。
-
恭喜你终于把这个归档为一个正确的错误。
-
@MaryEllenBench:该错误已修复。我不知道错误报告在哪里。我刚刚写信给微软的 Maoni Stephens,她立即修复了它。