Win32Exception Недостаточно памяти для обработки этой команды
Через мою автоматическую коллекцию сбоев для MaxTo Я получил следующий отчет о сбое:
V8.12.0.0 - System.ComponentModel.Win32Exception - :Void UpdateLayered():0
Version: MaxTo8.12.0.0
Exception: System.ComponentModel.Win32Exception
Error message: Not enough storage is available to process this command
Stack trace:
at System.Windows.Forms.Form.UpdateLayered()
at System.Windows.Forms.Form.OnHandleCreated(EventArgs e)
at System.Windows.Forms.Control.WmCreate(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ContainerControl.WndProc(Message& m)
at System.Windows.Forms.Form.WmCreate(Message& m)
at System.Windows.Forms.Form.WndProc(Message& m)
at MaxTo.MainForm.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
Еще один стек:
Version: MaxTo2009.9.0.0
Exception: System.ComponentModel.Win32Exception
Error message: Not enough storage is available to process this command
Stack trace:
at System.Windows.Forms.Form.UpdateLayered()
at System.Windows.Forms.Form.OnHandleCreated(EventArgs e)
at System.Windows.Forms.Control.WmCreate(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ContainerControl.WndProc(Message& m)
at System.Windows.Forms.Form.WmCreate(Message& m)
at System.Windows.Forms.Form.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
В этой последней трассировке стека вообще нет ссылки на MaxTo, и 90% сбоев, которые я получаю, имеют трассировку стека, аналогичную приведенной выше.
Чтение в сети, я нахожу, что эта ошибка обычна, если вы забудете освободить или удалить переменные. При просмотре моего WndProc
, который, кажется, иногда проходит через эту проблему, я не могу найти ни одного места, которое зависает от ссылок на какие-либо объекты. Все, кроме одной из переменных, являются локальными для WndProc и поэтому должны быть собраны в мусор, когда метод завершается.
protected override void WndProc(ref Message m)
{
base.WndProc(ref m); // I'm assuming the first trace can be caught here
IntPtr hwnd = m.WParam;
// Our hook tells us something got maximized
if (Win32Import.UWM_MAXIMIZE == (UInt32)m.Msg)
{
// Figure out if we are temporarily disabled or using alternative profiles
KeyStateInfo keyState = KeyboardInfo.GetKeyState(Settings.AlternativeProfileKey);
Rectangle r = FindRectangle(MousePosition, (Settings.EnableAlternativeProfile && keyState.IsPressed ? AlternativeRegions : Regions));
// Did we find a rectangle to place it in?
if (r != Rectangle.Empty)
{
Rectangle position = Win32Import.GetWindowRectangle(hwnd);
Rectangle previousPos = GetLocation(hwnd);
if (position == r && previousPos != Rectangle.Empty)
{
// We are restoring the original position
Win32Import.SetWindowPos(hwnd, IntPtr.Zero, previousPos.X, previousPos.Y, previousPos.Width, previousPos.Height, Win32Import.SWP_NOZORDER | Win32Import.SWP_NOSENDCHANGING);
}
else
{
// We are maximizing to a region
Win32Import.ShowWindow(hwnd, Win32Import.WindowShowStyle.Restore);
Win32Import.SetWindowPos(hwnd, IntPtr.Zero, r.X, r.Y, r.Width, r.Height, Win32Import.SWP_NOZORDER | Win32Import.SWP_NOSENDCHANGING);
// Make sure we remember this location
RememberLocation(hwnd, position);
}
}
}
else if (MaxTo64WindowHandleMessage == m.Msg)
{
// Store the window handle of our 64-bit subprocess
SubProcess64WindowHandle = m.WParam;
}
}
Я не смог воспроизвести ошибку даже при запуске программы в течение нескольких дней.
Мое предположение заключается в том, что система находится на низкой или безфрагментированной памяти или в ручках GDI, но я ничего не могу подтвердить. Кажется, что не существует хорошей документации по этой ошибке.
Любые идеи, что еще может быть? Могу ли я сделать что-нибудь, чтобы предотвратить эту ошибку?
Обновить. Вопрос был повторно открыт с большим количеством трассировок стека из-за отсутствия достойного решения. Просто игнорирование этого не решает проблему.
Ответы
Ответ 1
Утечка или использование многих объектов/дескрипторов GDI. Это может вызвать нехватку ресурсов. Возможно, вы не сможете воспроизвести, потому что у ваших пользователей могут быть другие тяжелые программы ресурса GDI, работающие или использующие Terminal Server, и в этом случае им приходится делиться некоторой кучей с другими пользователями. См. Системная ошибка. Код: 8. Недостаточно хранилища для обработки этой команды
Здесь вы можете прочитать о инструменте Desktop Heap Monitor для диагностики проблем кучи рабочего стола.
Здесь и здесь и здесь являются средства обнаружения утечки GDI.
Ответ 2
Ваша программа, вероятно, утечка ресурсов ядра. Начните диагностировать эту проблему с помощью Taskmgr.exe. Открыть + Выбрать столбцы, проверить объекты пользователя, объекты GDI и количество обработок. Запускайте свою программу и наблюдайте, неуклонно растет ли она. Как только один из них достигнет 10000, ваша программа умрет.
Чтобы быстро увидеть утечку в действии, вы можете начать комментирование кода, чтобы узнать, где происходит утечка. Вероятно, это связано с вашим "крючком".
Ответ 3
Проблема, вероятно, не лежит на вашем WndProc - причина, по которой вы видите это в своих стеках вызовов, состоит в том, что почти все графические интерфейсы, связанные с Windows, проходят через оконную процедуру WIN32. Переопределение этого в вашем контроле просто дает вам точку перехвата для обработки низкоуровневых материалов до того, как будет выполнена обработка .NET-платформы более высокого уровня.
Это будет полный выстрел в темноте, но, возможно, этот пост может иметь значение? - возможно, не с этими трассировками стека.
Ответ 4
У меня было много настраиваемых элементов управления Windows с собственными ресурсами, поэтому, когда я создаю много элементов управления, эта ошибка появляется. Чтобы устранить эту проблему
Я создал файл ресурсов в своей библиотеке и использовал внешние ресурсы вместо ресурсов на свой код компонента.
После этого мое исключение исчезло, уже протестировано с 3 раза более открытыми формами, и эта ошибка исчезла.
Так выглядит это решение.