6 Stimmen

Out of Memory Exception bei System.Drawing.Graphics.FromHdcInternal aber kein Speicherleck

Ich erhalte einen sehr gelegentlichen Absturz mit der folgenden Spur:

System.OutOfMemoryException: Out of memory.
   at System.Drawing.Graphics.FromHdcInternal(IntPtr hdc)
   at System.Windows.Forms.PaintEventArgs.get_Graphics()
   at System.Windows.Forms.Control.PaintBackColor(PaintEventArgs e, Rectangle rectangle, Color backColor)
   at System.Windows.Forms.Control.PaintBackground(PaintEventArgs e, Rectangle rectangle, Color backColor, Point scrollOffset)
   at System.Windows.Forms.Control.PaintBackground(PaintEventArgs e, Rectangle rectangle)
   at System.Windows.Forms.Control.OnPaintBackground(PaintEventArgs pevent)
   at System.Windows.Forms.ScrollableControl.OnPaintBackground(PaintEventArgs e)
   at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer, Boolean disposeEventArgs)
   at System.Windows.Forms.Control.WmEraseBkgnd(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.UserControl.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)

Wie Sie sehen können theres keine meiner Code in der Spur, so finde ich es sehr schwer, die Ursache zu finden. Google-Suchen scheinen nicht schlüssig, aber in der Regel zeigen auf eine GC-Handle-Leck irgendwo aber nach dem letzten Absturz meine Speichernutzung war:

Handle count:16,283, 
Private Bytes:995,440K, 
Virtual Bytes:1,628,208K, 
Working Set:866,892K, 
GC Heap Size:158,841K, 
GDI Objects:402, 
User Objects:1,607 

Das scheint nicht ungewöhnlich zu sein. Außerdem verwende ich regelmäßig den .net memory profiler, um Lecks zu verwalten.

Leider ist meine Anwendung recht umfangreich mit vielen Windows, so dass meine erste Frage lauten würde: Wie kann ich herausfinden, welches Fenster die ganzen Probleme verursacht?

und dann wäre natürlich meine zweite Frage: Wenn es kein Handle-Leck gibt, was ist dann die Ursache der Ausnahme?

Edita:

Leider kann ich keinen Code posten: Es ist ein massiver Codebase und die Ausnahmen nicht gerade geben mir keine Hinweise darauf, welcher Teil kann das Problem sein.

Ich habe gelesen, dass es ein 10.000-Limit für Handles gibt, aber diese App hat in der Vergangenheit immer mit 15.000 gut funktioniert, sodass ich annahm, dass die Grenze auf etwas anderes lag: GDI-Handles oder Benutzerobjekte vielleicht?

Um sicherzugehen, habe ich es überprüft, und die Handles werden nicht durchgelassen, da sie beim Start zugewiesen werden und sich nicht mit der Nutzung erhöhen.

Lassen Sie mich meine Frage ändern: Was sollte angesichts dieser Informationen die nächste Vorgehensweise sein? Ich habe den Prozess-Explorer installiert und es ist mir gelungen, einen vollständigen Speicherauszug von einem der Abstürze zu erhalten, aber ich habe wirklich keine Erfahrung mit der Verwendung von beidem, um diese Art von Problem zu diagnostizieren (bis jetzt war der .net memory profiler ausreichend)

3voto

Femaref Punkte 59547

Wahrscheinlich weisen Sie Pinsel oder Stifte zu und entsorgen sie nicht - das verbraucht GDI-Handles und irgendwann werden alle verwendet und Sie erhalten eine OutOfMemoryException.

0voto

MasterMastic Punkte 19896

Da wir den Code nicht sehen können, gibt es eine Möglichkeit für diesen Fehler. Das ist mir gerade passiert.

Vergewissern Sie sich, dass Sie die richtige Methode aufrufen. Ich habe versucht, eine Graphics Objekt von HDC und ich sollte die Methodenüberladung wählen, die stattdessen ein HWND nimmt. Es ist ziemlich einfach, hier in diese Fehler zu verfallen, da es keinerlei Typüberprüfung zwischen diesen Handles gibt.

0voto

FrankyB Punkte 687

Spät dran, aber für den Fall, dass jemand anderes hier landet, aber es gibt einen Hotfix, der veröffentlicht wurde: https://support.microsoft.com/en-us/help/2650146/fix-outofmemoryexception-exception-when-you-use-a-graphics-object-to-p

FIX: OutOfMemoryException-Ausnahme bei Verwendung eines Grafikobjekts zum Zeichnen in einer .NET Framework 3.5-basierten Windows Forms-Anwendung Gilt für: .NET Framework 3.5 Service Pack 1

Symptome Stellen Sie sich das folgende Szenario vor:

  • Sie erstellen eine Microsoft .NET Framework 3.5-basierte grafikintensive Anwendung auf einem Computer, der Windows 7 oder Windows Server 2008 R2 ausgeführt wird.
  • Die Anwendung verwendet die Schnittstelle für Grafikgeräte (GDI).
  • Sie erstellen ein Grafikobjekt, und verwenden es dann zum Malen. In diesem Szenario kann es zu einer OutOfMemoryException-Ausnahme auftreten. Außerdem erhalten Sie die folgende Fehlermeldung:

Art der Ausnahme: System.OutOfMemoryException Meldung: Kein Speicherplatz vorhanden.

Wenn Sie dieses Problem debuggen, erhalten Sie eine Stapelverfolgung, die wie folgt aussieht dem Folgenden ähnelt:

at System.Drawing.Graphics.FromHdcInternal(IntPtr hdc)

at System.Windows.Forms.PaintEventArgs.get_Graphics()

Zu lösen:

Ein unterstützter Hotfix ist jetzt von Microsoft verfügbar. Es ist jedoch soll jedoch nur das Problem beheben, das in diesem Artikel beschrieben wird. Wenden Sie ihn nur auf Systeme an, bei denen dieses spezielle Problem auftritt.

Um dieses Problem zu lösen, wenden Sie sich an den Microsoft-Kundendienst um den Hotfix zu erhalten. Eine vollständige Liste der Microsoft Customer Support Services und Informationen zu den Supportkosten Kosten finden Sie auf der folgenden Microsoft-Website: http://support.microsoft.com/contactus/?ws=support

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X