为什么并发GC有时会导致ExecutionEngineException(根据MSDN)?

12
根据MSDN,有一个“提示”指出,在使用并发垃圾回收(<gcConcurrent enabled="true"/>或未指定,因为这是默认行为)的重载.NET应用程序可能会抛出ExecutionEngineException异常。是否有人知道微软KB文章或其他提供有关此问题的背景信息的来源?
我们在基于NHibernate 3.2的Windows服务应用程序中直接遇到了这个问题,该应用程序在最多几个小时的操作后必定会崩溃。我们能够追踪到ISession.Flush()调用引起的异常。
在nhusers上有一个thread报告了似乎是相同的问题。他建议的解决方法是禁用并发GC,这对我们至今有效,尽管切换到服务器模式GC(<gcServer enable="true"/>),它隐式地禁用了并发GC,也起到了作用。
在将此提交给MS作为错误之前,我想找出是否有任何人对提示提到的并发GC不稳定性有额外的信息。

2
考虑到它已经被记录,你的 bug 很可能会被标记为“按设计”。不过,这是一个有趣的问题。 - vcsjones
2
@Nick Jones:.NET 4.0文档也将其列为弃用,并指出运行时不再抛出此异常。 - casperOne
@casperOne:已经注意到了,但是NH 3.2是针对.NET 3.5编译的。 - Nick Jones
@Nick:你可以为.NET 4.0重新编译NHibernate。请参见https://dev59.com/KUrSa4cB1Zd3GeqPSwA0 - TrueWill
1个回答

5
我怀疑这种情况发生在应用程序负载较重时,因为启用并发GC时,GC会在不暂停您的应用程序的情况下完成其工作。如果GC在GC周期的压缩阶段尝试移动内存但无法移动内存或无法正确更新应用程序指针,则可能导致运行时抛出此异常,因为它会将应用程序置于潜在的无效状态。
正如@casperOne在他的评论中指出的那样,虽然在.NET 4.0中将此异常标记为过时,但这并不一定意味着GC仍然不能陷入导致在.NET 3.5中引发异常的相同状态。如果GC确实陷入了相同的状态,运行时将发出FailFast命令并终止,而不是抛出异常。

1
请注意,虽然“API”已被标记为过时,但该错误确实发生在 .NET 4.0 中(例如此 SO 线程:应用程序崩溃并显示“.NET Runtime 内部错误”)。MSDN KB 条目将其描述为 x64 .NET 4 问题,但我不敢肯定它仅限于 x64。我们曾经遇到过同样的问题,也涉及到了 NHibernate,并关闭并发 GC 可以解决它。早上来上班看到我们的主服务器应用程序因内部 .NET 异常而崩溃真是太糟糕了。 :) - vgru

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接