.NET 4.5:.NET运行时内部错误(80131506)/禁用并发GC

我有一个长期运行的.NET 4.5应用程序随机崩溃,留下我在事件日志中的问题标题中提到的消息。 该问题在3个不同的机器和2个不同的系统(2008 R2和2012)上重现。 应用程序不使用任何不安全/非托管组件,它是纯托管.NET,唯一不受管理的东西是CLR本身。

这是我从转储中提取的崩溃站点的堆栈跟踪:

clr.dll!MethodTable::GetCanonicalMethodTable() clr.dll!SVR::CFinalize::ScanForFinalization() - 0x1a31b bytes clr.dll!SVR::gc_heap::mark_phase() + 0x328 bytes clr.dll!SVR::gc_heap::gc1() + 0x95 bytes clr.dll!SVR::gc_heap::garbage_collect() + 0x16e bytes clr.dll!SVR::gc_heap::gc_thread_function() + 0x3e bytes clr.dll!SVR::gc_heap::gc_thread_stub() + 0x77 bytes kernel32.dll!BaseThreadInitThunk() + 0x1a bytes ntdll.dll!RtlUserThreadStart() + 0x21 bytes 

这个问题与这里讨论的问题非常相似,所以我尝试了该主题中提出的解决方案,但没有一个帮助:

  • 我已经尝试安装此修补程序,但它不会安装在我的任何机器上(KB2640103不适用,或被计算机上的其他条件阻止),这实际上是有道理的,因为我使用的是4.5,而不是4.0 。

  • 我已经尝试禁用并发GC和/或启用服务器GC。 现在我的app.config的相关部分如下所示:

             

虽然奇怪的是我仍然在进程转储中找到多个与GC相关的线程。 除了发生崩溃之外,还有7个线程具有以下堆栈跟踪:

 ntdll.dll!NtWaitForSingleObject() + 0xa bytes KERNELBASE.dll!WaitForSingleObjectEx() + 0x9a bytes clr.dll!CLREventBase::WaitEx() + 0x13f bytes clr.dll!CLREventBase::WaitEx() + 0xf7 bytes clr.dll!CLREventBase::WaitEx() + 0x78 bytes clr.dll!SVR::t_join::join() + 0xd8 bytes clr.dll!SVR::gc_heap::scan_dependent_handles() + 0x65 bytes clr.dll!SVR::gc_heap::mark_phase() + 0x347 bytes clr.dll!SVR::gc_heap::gc1() + 0x95 bytes clr.dll!SVR::gc_heap::garbage_collect() + 0x16e bytes clr.dll!SVR::gc_heap::gc_thread_function() + 0x3e bytes clr.dll!SVR::gc_heap::gc_thread_stub() + 0x77 bytes kernel32.dll!BaseThreadInitThunk() + 0x1a bytes ntdll.dll!RtlUserThreadStart() + 0x21 bytes 

这让我想知道我是否能以某种方式搞砸禁用并发GC(这就是我实际列出的配置)。

我认为这包含了我迄今为止找到的内容。 我真的可以使用一些帮助来处理这个问题。

我从我过去在申请中的经验中汲取经验。 如果exception未处理到Finalizer级别,可能会导致这种情况,如果它发生了……它将使应用程序崩溃。

在对GC配置进行任何操作之前..

快速检查一下…… 您使用的是任务并行库吗? 如果是,请确保正确处理exception 。 如果来自不同线程的exception未处理,则直到Finalizer然后崩溃应用程序。 有几种方法可以整齐地处理它们。 处理’聚合’exception是一种方式(我们过去常常解决!)。

http://msdn.microsoft.com/en-us/library/dd537614.aspx

我没有50分来添加评论,所以添加它作为答案……

帮助我的解决方案:卸载.NET 4.5.1,安装4.0,安装提到的修补程序,安装4.5.1。

我刚刚与微软完成了一次对话,因为我能够重现一个类似的问题。

在我的例子中,它是.NET运行时中的一个错误,它与混合动态类型和非动态代码有关。 我不确定你的场景中是否也是这种情况,但有些事情你可能想尝试:

  • 在Windows 8.1(最新更新)上运行代码。 显然,Windows 8.1比其他版本的Windows具有更新版本的.NET。
  • 如果您使用AssemblyBuilder(就像我一样),请尝试将其更改为Run模式而不是RunAndCollect
  • 将运行时更改为x86或x64,然后重试; 您也可以使用已经尝试的并发GC设置。
  • 我们说话时我的错误正在修复,这基本上意味着会有一个Windows更新来处理它。 或许也可以选择等待; 我不希望这花费太长时间,因为它对很多程序来说非常关键。

我终于找到了一个可以安装的修复程序。 我也有4.5和4.0的其他修复程序没有安装。 删除4.5也没有解决它。 修复链接实际修复它。

http://kb.machsol.com/Knowledgebase/Article/50305

我意识到这是一个老post,然而,我遇到了与OP相同的问题。 点测试表

将运行时更改为x86或x64,然后重试; 您也可以使用已经尝试的并发GC设置。

对我来说是关键。 我的所有项目都设置为任何CPU,除了一个(巧合的是应用程序的入口点,它是一个控制台应用程序项目)。 该项目设置为x86。 一旦我将其更改为任何CPU ,应用程序就可以正常运行。

我们在.NET 4.5桌面应用程序中遇到了同样的问题 – 网络刮刀。 它在重负荷下随机坠毁。 所以我们一直在寻找方法来找出几个月的原因:我们已经尝试了一切! 禁用并发GC,将其设置为服务器模式以及许多其他解决方法,直到我们意识到由于PhantomJS模块而发生崩溃。 它使用了一些非托管资源,之后不会清除它们:(所以我们为PhantomJS集成创建了一个独立的控制台应用程序。现在我们用Web刮刀从Process.Start执行这个控制台应用程序并在之后杀死它。更多的时间刮,但没有更多的崩溃!

我的问题很奇怪,每隔5-10分钟我的应用程序池就会出现这个退出代码(80131506)。 我不确定在高线程操作/计划任务中你应该推动垃圾收集器,但以下解决方案适用于此处。

我添加了一个每分钟调用GC.GetTotalMemory(true)的Job。 我认为,由于某种原因,GC不会经常自动调用垃圾收集器来处理我使用的大量一次性对象。 但这解决了我的问题! 它更像是一个快速解决方案而不是最终解决方案;)