System.Drawing.Graphics.FromHdcInternal的内存不足异常,但没有内存泄漏

daz*_*ddy 5 .net out-of-memory

以下跟踪非常偶然地导致崩溃:

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)
Run Code Online (Sandbox Code Playgroud)

如您所见,跟踪中没有我的代码,因此我很难找到原因。Google搜索似乎尚无定论,但通常指向某个地方的GC句柄泄漏,但是在最近一次崩溃之后,我的内存使用情况是:

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 
Run Code Online (Sandbox Code Playgroud)

这似乎并不与众不同。另外,我定期使用.net内存分析器来管理泄漏。

不幸的是,我的应用程序很大,有很多窗口,所以我的第一个问题是:如何确定哪个窗口引起了所有麻烦?

然后我的第二个问题当然是:如果没有句柄泄漏,是什么导致异常!?

编辑:

抱歉,我无法发布任何代码:它的代码库庞大,并且没有任何异常,这给了我关于哪部分可能是问题的任何线索。

我听说句柄有10,000个限制,但是从历史上看,这个应用程序始终运行良好,只有15,000个,因此我认为这个限制是在其他方面:GDI句柄或用户对象?

只是为了确保,我检查了这些句柄并没有泄漏,因为它们都是在启动时分配的,并且不会随使用量增加。

让我修改一下我的问题:有了这些信息,下一步应该采取什么行动?我已经安装了Process Explorer,并且已经成功从其中一个崩溃中获取了完整的内存转储,但实际上没有使用任何一种诊断此类问题的经验(直到现在.net内存探查器已经足够了)

Fem*_*ref 3

您可能正在分配画笔或笔,但没有处理它们 - 这会消耗 GDI 句柄,并且在某些时候,所有这些都被使用,并且您会收到 OutOfMemoryException。