Win32Exception Não há armazenamento suficiente disponível para processar este comando

Através da minha colecção de colisões automatizada para MaxTo recebi o seguinte relatório de falha:

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) 

Outro stacktrace:

 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) 

Neste rastreamento de pilha mais recente, não há nenhuma referência ao MaxTo, e 90% dos travamentos que recebo são com rastreamentos de pilha semelhantes aos anteriores.

Ao ler na net, acho que esse erro é comum se você esquecer de liberar ou descartar variables. Ao olhar através do meu WndProc , que às vezes parece que o problema está passando, não consigo encontrar um único local que fique ligado a referências a qualquer object. Todas, exceto uma das variables, são locais para WndProc e, portanto, devem ser coletadas quando o método é finalizado.

 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, rX, rY, 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; } } 

Eu não fui capaz de reproduzir o erro, mesmo durante a execução do programa durante vários dias.

Minha suposição é que o sistema tem pouca memory não fragmentada ou identificadores GDI, mas não posso confirmar isso em nenhum lugar. Não parece haver nenhuma boa documentação sobre esse erro.

Alguma idéia do que mais poderia ser? Posso fazer algo para evitar esse erro?

Atualização : A questão foi reaberta com mais rastros de pilha, devido à falta de uma solução decente. Simplesmente ignorá-lo não resolve o problema.

Vazamento ou uso para muitos objects / manipulações GDI. Aqueles poderiam causar uma escassez de heap de resources. Você pode não conseguir reproduzir porque seus usuários podem ter outros programas pesados ​​de resources GDI em execução ou usar o Terminal Server, caso em que eles precisam compartilhar parte do heap com os outros usuários. Veja o erro do sistema. Código: 8. Não há armazenamento suficiente disponível para processar este comando

Aqui você pode ler sobre a ferramenta Desktop Heap Monitor para diagnosticar problemas de heap da área de trabalho.

Aqui e aqui e aqui estão as ferramentas de detecção de vazamentos do GDI.

Seu programa provavelmente está vazando resources do kernel. Comece a diagnosticar esse problema com Taskmgr.exe. Ver + Selecione Colunas, marque Objetos do usuário, objects GDI e Contagem de identificadores. Execute o seu programa e observe se algum deles está aumentando constantemente. Quando um deles atingir 10.000, o seu programa irá morrer.

Com uma maneira de ver rapidamente o vazamento em ação, você pode começar a comentar o código para ver onde o vazamento ocorre. Provavelmente tem algo a ver com o seu “gancho”.

O problema provavelmente não está em seu WndProc – a razão pela qual você o vê em suas pilhas de chamadas é porque praticamente tudo relacionado à GUI no Windows passa pelo procedimento de janela do WIN32. Sobrescrevê-lo em seu controle simplesmente lhe dá um ponto de gancho para processar material de baixo nível antes que o processamento de alto nível do .NET Framework seja feito.

Isto vai ser um tiro completo no escuro, mas talvez este post possa ser relevante? – Provavelmente não com esses rastros de pilha, no entanto.

Eu tinha muitos controles personalizados do Windows com resources próprios, por isso, quando eu crio muitos controles, esse erro é exibido. Para corrigir esse problema, fiz o arquivo de resources em minha biblioteca e usei resources externos em vez de resources no código do meu componente. Depois disso minha exceção se foi, já testada com 3 vezes mais formulários abertos e esse erro desaparecido. Então parece que é uma solução.