你能重新编程这个64位的.NET 4 GC错误吗?

你能重新编程这个64位的.NET 4 GC错误吗?,.net,garbage-collection,.net,Garbage Collection,更新:微软现在已经复制了该漏洞,并正在进行修复 在评估.NET平台用于低延迟软件开发的可行性时,我们发现.NET 4并发工作站垃圾收集器中存在一个严重缺陷,该缺陷可能导致应用程序一次最多挂起几分钟 在我们的三台机器上,以下简单的C#程序会导致GC泄漏内存,直到没有剩余内存,一个庞大的GC循环开始,程序会暂停几分钟(!),同时回收11Gb的堆: static void Main(string[] args) { var q = new System.Collecti

更新:微软现在已经复制了该漏洞,并正在进行修复

在评估.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();
        }
    }
static void Main(字符串[]args)
{
var q=new System.Collections.Generic.Queue();
while(true)
{
q、 排队(0);
如果(q.计数>1000000)
q、 出列();
}
}
您需要在带有.NET 4的64位Windows操作系统上编译x64,并使用默认(交互式)延迟设置以默认(并发工作站)GC运行。

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

注意,当这个程序需要不超过100Mb的内存时,11Gb的堆在这里被泄漏


我们现在已经积累了大约12个这个bug的复制品,它们是用F#和C#编写的,并且它似乎与gen0大部分存活时GC写屏障中的一个bug有关。然而,微软还没有能够复制它。你能?如果是这样的话,请您尽可能准确地描述您的设置,以便我们可以尝试精确地缩小此错误出现所需的条件。

如果以64位运行,在linqpad中运行代码确实会导致巨大的内存消耗;以32位的方式运行很好

我有一个Windows7x64终极安装(像往常一样打补丁),主内存为8GB;安装了VS.NET和其他开发工具,因此可能存在一些奇怪的调试器挂钩,而这些挂钩在其他空白计算机上不存在

奇怪的是,他们没有重做。你确定那里没有通信中断吗


哦,使用“new object()”而不是装箱的值类型会导致同样的问题(毫不奇怪),因此您可能希望从您的复制案例中删除装箱的混淆因素。

我无法复制它。我在一个4 gigs ram的x64上尝试了它&编译为任意大小。最大内存使用量约为2.5 Gig。最大GC暂停时间约为1084 ms

这是我的GC ETW统计数据的输出。

您还可以按时间获取GC事件

也许跑步中类似的跟踪输出有助于理解封面下发生的事情

在.NET 4.0中,有一种Windows事件跟踪(ETW),它提供框架跟踪信息。这是一个特定于

为了得到这些信息,有一个叫做

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

  • 以管理员身份启动cmd.exe,这是收集ETW跟踪所必需的
  • 启动要跟踪的应用程序
  • 发出命令“PerfMonitor.exe/process:4180 start”,其中4180是进程id
  • 让应用程序运行一段时间
  • 然后发出“PerfMonitor.exe停止”
  • 获取报告“PerfMonitor.exe GCTime”的命令。这将生成一个报告,并在浏览器中用GC stats打开它
    使用serverGC时会发生什么情况?.NET内存性能计数器会显示什么?@leppie:使用其他GC选项或其他GC(包括服务器)可以避免该错误。然而,并发工作站GC是微软提供的唯一低延迟稳定状态选项,我们希望低延迟。当然,服务器GC的延迟通常要差得多。微软对其GC算法讳莫如深,但我相信服务器GC是幼稚的,用并行遍历来阻止世界。祝贺你最终将此文件作为一个适当的错误提交。@MaryEllenBench:错误已经修复。我不知道错误报告在哪里。我刚写信给微软的Maoni Stephens,她马上就修好了。谢谢!“你确定那里没有通信中断吗?”也许。我已经将复制作为C#解决方案交给MS的其他人测试。“您可能需要删除混淆因素。”好主意,可以。谢谢您对
    PerfMonitor
    的参考。根据该工具,此处最长的暂停时间仅为618ms,但更仔细的检查显示,每隔60-130ms定期暂停18ms,但在最长的618ms GC暂停之前有一个巨大的145s间隙。因此,我的时间并没有浪费在
    PerfMonitor
    认为是GC暂停的事情上。微软的Maoni Stephens和这个垃圾收集器的作者说:“这是GC暂停。PerfMonitor没有足够的信息来识别它。”。