Я пытаюсь отлаживать некоторую работу, обрабатывающую большие файлы. Сам код работает, но есть спорадические ошибки из самого .NET Runtime. Для контекста обработка здесь представляет собой файл размером 1,5 ГБ (только один раз в памяти), который обрабатывается и освобождается в цикле, преднамеренно пытается воспроизвести эту непредсказуемую ошибку.
Мой тестовый фрагмент в основном:
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
}
(с некоторыми моментами и другими вещами, которые были брошены)
Цикл будет обрабатываться отлично для недетерминированного числа итераций полностью успешно - никаких проблем вообще; то процесс прекратится резко. Обработчик исключений не попадает. Тест действительно требует много использования памяти, но он видел очень хорошо во время каждой итерации (нет очевидной утечки памяти, и у меня много запаса прочности - 14 ГБ неиспользуемой первичной памяти на худшем точка в пиле). Этот процесс является 64-разрядным.
Журнал ошибок Windows содержит 3 новые записи, которые (через код выхода 80131506) указывают на ошибку Engine Engine - неприятный маленький тредтер. Ответ , предлагает ошибку GC с "исправлением", чтобы отключить параллельный GC; однако это "исправление" не предотвращает проблему.
Уточнение: эта ошибка низкого уровня не попадает в событие CurrentDomain.UnhandledException
.
Уточнение: GC.Collect
существует только для наблюдения за памятью пильного диска, для проверки утечек памяти и сохранения предсказуемости; удаление его не устраняет проблему: он просто заставляет больше хранить память между итерациями и делает файлы dmp больше, p
Добавив больше трассировки консоли, я заметил, что это ошибка во время каждого из:
- во время десериализации (много распределений и т.д.)
- во время GC (между подходом GC) и GC "complete", используя API уведомления GC)
- во время проверки (просто
foreach
по некоторым данным) - любопытно сразу после GC завершается во время проверки
Так много разных сценариев.
Я могу получить файлы crash-dump (dmp); как я могу исследовать это дальше, чтобы увидеть, что делает система, когда она терпит неудачу настолько эффектно?