Журнал WinForms состояние приложения - PullRequest
0 голосов
/ 28 ноября 2018

У нас есть приложение WinForms, которое иногда генерирует исключения OutOfMemory.Мы не смогли выдать эту ошибку ни на одной машине разработки, но иногда это случается с некоторыми нашими клиентами.Я уверен, что это вызвано не утечкой памяти, а приложением, которое пытается обработать слишком много данных.Это имеет смысл, поскольку только несколько крупнейших клиентов сталкиваются с этой проблемой.Проблема, однако, в том, что я понятия не имею, что они делают, когда это происходит.Мы попытались спросить их, и ответ - что-то вроде: «Это случается несколько раз».У нас есть служба отчетов об исключениях, которая регистрирует все необработанные исключения, возникающие в рабочей среде, но из-за того, как работает нехватка памяти, виновник не обязательно находится в стеке вызовов.Я никогда не видел ни одного нашего кода в стеке вызовов для этих проблем.

Есть ли способ определить, что происходит в приложении, когда эти исключения генерируются?Например, какие окна открыты и какая (сколько) информация отображается в элементах управления этих окон и т. Д.

Вот несколько примеров стеков вызовов:

Сообщение: исключение типа«System.OutOfMemoryException» было сгенерировано.System.Threading.WaitHandle.WaitAny (WaitHandle [] waitHandles, Int32 millisecondsTimeout, логический exitContext) System.Net.TimerThread.ThreadProc (): 436 System.Threading.ThreadHelper.ThreadStart_Context (состояние объекта): 20.(ExecutionContext executeContext, обратный вызов ContextCallback, состояние объекта, Boolean preserveSyncCtx): 112 System.Threading.ExecutionContext.Run (обратный вызов ExecutionContext executeContext, ContextCallback, состояние объекта, Boolean preserveSyncCtx): 0 System.Threading.ExbacktionConnextContext, Состояние объекта): 43 System.Threading.ThreadHelper.ThreadStart (): 8

-

Сообщение: исключение типа 'System.OutOfMemoryException' было сгенерировано.System.Reflection.Assembly.GetName (): 0 System.Windows.Forms.ThreadExceptionDialog..ctor (исключение t): 1033 System.Windows.Forms.Application + ThreadContext.OnThreadException (исключение t): 57 System.Windows.Forms.Control.WndProcException (Исключение e): 0 System.Windows.Forms.Control + ControlNativeWindow.OnThreadException (исключение e): 0 System.Windows.Forms.NativeWindow.Callback (IntPtr hWnd, Int32 msg, интервал IntPtr, интервал IntPtr): 58

1 Ответ

0 голосов
/ 28 ноября 2018

Здесь можно найти одно из лучших объяснений того, чего нет.

https://blogs.msdn.microsoft.com/ericlippert/2009/06/08/out-of-memory-does-not-refer-to-physical-memory/

Основная идея заключается в том, что в современных ОС Windows компьютер взорвется и умретдо того, как закончится память.Потребуется каждый байт жесткого диска, и он будет меняться так сильно, что вы заметите ужасные замедления задолго до того, как на самом деле закончится память.

Итак, что такое «OutOfMemoryException» и почему они происходят?Ну, есть несколько причин, в некоторой степени связанных с памятью, и некоторые причины, которые вообще не имеют ничего общего с памятью.

Самый распространенный источник этой ошибки: GDI + вызывает с неверными параметрами.Любая ошибка из GDI +, включая использование библиотек System.Drawing, вызывает исключение OutOfMemoryException.Похоже, это связано с тем, что базовый API не предоставляет никакой информации .NET о том, почему он вышел из строя, поэтому создатели .NET решили назвать их все OutofMemoryException, и теперь они придерживаются его для совместимости.Такие вещи, как попытка создать перо 0 размера или растровое изображение с ошибочными флагами, приводят к «Out of Memory»

. Причина, по которой .NET, возможно, использовала OutOfMemory для ошибок GDI, состоит в том, что на самом деле многие ошибкинесколько связанных с памятью.Все еще доступно ограниченное количество дескрипторов GDI.Это может быть пара миллионов, но все же ограничено, поэтому, если что-то просачивается в базовый HBITMAP или HBRUSH или HPEN, в конце концов он заканчивается, GDI вызывает сбой, и вы получаете исключение.

Другое место, где я 'Я видел ошибку, используя любой интерфейс COM.Если COM-объект возвращает ошибку, вы можете получить исключение OutOfMemory.Я пытаюсь отловить и обработать эти ошибки.

Для отслеживания просмотрите вызовы, связанные с GDI / System.Drawing.Посмотрите на трассировку стека, она показывает вам проблему.

Кроме того, не думайте, что ошибка «OutOfMemory» должна закрыть приложение.Вы должны быть в состоянии нормально восстановиться после этих исключений, потому что у вас на самом деле не хватает памяти.Почему клиент даже видит эту ошибку?

...