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

时间:2013-10-03 08:11:17

标签: c# .net garbage-collection clr .net-4.5

我有一个长期运行的.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    

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

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

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

    <?xml version="1.0"?>
    <configuration>        
        <runtime>
            <gcConcurrent enabled="false"/>
            <gcServer enabled="true" />
        </runtime>
    <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>    </startup></configuration>
    

虽然奇怪的是我仍然在进程转储中找到多个与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(这就是我实际列出的配置)。

我认为这包含了我迄今为止找到的内容。我真的可以帮助解决这个问题。

7 个答案:

答案 0 :(得分:5)

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

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

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

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

我没有50分来添加评论,所以将其添加为答案......

答案 1 :(得分:1)

我意识到这是一个老帖子,然而,我遇到了与OP相同的问题。点 atlaste

  

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

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

就我而言,它是.NET运行时中的一个错误,它与混合动态类型和非动态代码有关。我不确定您的方案中是否也是这种情况,但有些事情您可能想尝试:

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

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

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

答案 6 :(得分:0)

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

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