你能复制这个64位.NET 4 GC错误吗?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (18)

微软现在已经重现了这个错误,并正在努力解决问题。

在评估用于低延迟软件开发的.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#编写的这个bug的repros,当gen0的大部分存活时,它似乎与GC写屏障中的一个bug有关。但是,微软还没有能够重现它。你可以吗?如果是这样,能否请尽可能准确地描述设置,以便我们可以尝试缩小该错误所需的条件。

提问于
用户回答回答于

如果以64位运行,在linqpad中运行代码确实会导致巨大的内存消耗; 以32位运行正常工作。

我有一个Windows 7 x64终极安装(像往常一样修补)与8GB的主内存; VS.NET和其他开发工具被安装,所以可能会有一些奇怪的调试器挂钩,这些挂钩在空白的机器上不存在。

奇怪他们没有责备它。你确定那里没有通讯故障吗?

哦,并且使用“new object()”而不是装箱值类型会导致相同的问题(不出所料),所以您可能想从重新生成的案例中删除混淆因素。

用户回答回答于

我无法复制它。我在x64上试了4次演出,并且编译成了ANY。最大内存使用量约为2.5个演出。最大GC暂停时间大约为1084毫秒。

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

也可以按时间获取GC事件

运行中的类似跟踪输出可能有助于理解封面下面发生的情况。

在.NET 4.0中,存在提供框架跟踪信息的Windows事件跟踪(ETW)。这是GC特有的一个。

为了获得这些信息,有一个称为PerfView的工具

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

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

扫码关注云+社区