我正在尝试调试一些处理大文件的工作。代码本身可以工作,但 .NET 运行时本身会报告零星错误。就上下文而言,这里的处理是一个 1.5GB 的文件(仅加载到内存中一次)在循环中处理和释放,故意尝试重现这个不可预测的错误。
我的测试片段基本上是:
try {
byte[] data =File.ReadAllBytes(path);
for(int i = 0 ; i < 500 ; i++)
{
ProcessTheData(data); // deserialize and validate
// force collection, for tidiness
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
}
} catch(Exception ex) {
Console.WriteLine(ex.Message);
// some more logging; StackTrace, recursive InnerException, etc
}
(加上一些时间和其他东西)
对于不确定的迭代次数,循环将完全成功地处理 - 没有任何问题;然后该过程将突然终止。异常处理程序未命中。该测试确实涉及大量内存使用,但它在每次迭代期间都非常好地锯齿(没有明显的内存泄漏,而且我有足够的空间 -在锯齿中最糟糕的点有 14GB 未使用的主内存) . 该进程是 64 位的。
Windows 错误日志包含 3 个新条目,其中(通过退出代码 80131506)表明执行引擎错误 - 一个讨厌的小动物。一个相关的答案,暗示了一个 GC 错误,并带有一个“修复”来禁用并发 GC;然而,这个“修复”并不能阻止这个问题。
澄清:这个低级错误不会影响CurrentDomain.UnhandledException
事件。
澄清:GC.Collect
这只是为了监视锯齿状内存,检查内存泄漏并保持可预测性;删除它不会让问题消失:它只是让它在迭代之间保留更多内存,并使 dmp 文件更大;p
通过添加更多控制台跟踪,我观察到它在以下每个过程中都会出现故障:
- 在反序列化期间(大量分配等)
- 在 GC 期间(在 GC“方法”和 GC“完成”之间,使用 GC 通知 API)
- 在验证期间(只是
foreach
在一些数据上) - 奇怪的是在验证期间 GC“完成”之后
所以很多不同的场景。
我可以获得崩溃转储(dmp)文件;我如何进一步调查这个问题,看看系统在发生如此严重的故障时在做什么?