更新: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#编写,当大多数gen0存活时,它似乎与GC写入障碍中的错误有关。但是,微软还没有能够重现它。你能?如果是这样,您能否尽可能准确地描述您的设置,以便我们可以尝试准确缩小此错误所需的条件。
答案 0 :(得分:3)
我无法重现它。我在x64上用4演出ram&amp;编译为ANY。最大内存使用量约为2.5 gigs。最大GC暂停时间约为1084毫秒。
以下是我的GC ETW统计数据的输出。
您还可以按时间获取GC事件
您的运行中可能有类似的跟踪输出可能有助于了解幕后发生的情况。
在.NET 4.0中,有用于Windows的事件跟踪(ETW),它提供了框架跟踪信息。这是GC特有的。
要获取此信息,有一个名为PerfView
的工具以下是使用该工具获取GC信息的步骤
答案 1 :(得分:2)
如果以64位运行,在linqpad中运行代码确实会导致大量内存消耗;以32位运行正常。
我有一个带有8GB主内存的Windows 7 x64终极安装(照常修补);安装了VS.NET和其他开发工具,因此可能会有一些奇怪的调试器挂钩,这些挂钩在其他空白机器上不存在。
奇怪的是他们没有责备它。你确定那里没有通讯故障吗?
哦,使用“new object()”而不是盒装值类型会导致同样的问题(不出所料),所以你可能想要从你的repro案例中删除拳击的混杂因素。
答案 2 :(得分:2)
我在博客上发表了这篇文章here,到目前为止还有六个人,除了我和Eamon之外,已经确认他们也可以重现这个错误。
此外,卡斯滕和迈克尔罗宾独立地重复了我的怀疑,即每次跑步都不会立即出现这个错误,而是随机出现,有时会在正常运行数十分钟后出现。换句话说,默认的.NET垃圾收集器是概率性的,可能会导致中断持续几分钟。