寻找EOutOfResources

时间:2010-02-01 21:53:44

标签: delphi gdi resource-leak eoutofresources

8 个答案:

答案 0 :(得分:11)

slim 有机会误认为该错误。 VCL天真地报告 EOutOfResources ,如果它无法获取窗口的DC(请参阅 Controls.pas 中的 TWinControl.GetDeviceContext )。

我说“天真地”,因为还有其他原因 GetDC() 可能会返回一个NULL句柄,而VCL应该报告操作系统错误,而不是假设资源条件(需要进行Windows版本检查才能可靠,但VCL可以而且应该采取这种方式)。

由于窗口句柄变得无效,我遇到了 EOutOfResources 错误。一旦我发现了真正的问题,找到原因并修复它很简单,但我浪费了很多,很多小时试图找到一个不存在的资源泄漏。

如果可能,我会检查导致此异常的堆栈跟踪 - 如果它来自 TWinControl.GetDeviceContext 那么问题可能不是你想的那样(不可能说它可能是什么)当然,但消除不可能性始终是发现解决方案的第一步,无论多么不可能)。

答案 1 :(得分:6)

如果他们是GDI句柄泄漏,您可以查看使用工具MSDN Magazine January 2003GDILeaks。其他工具包括GDIObjGDIView。另请参阅here

EOutOfResources的另一个来源可能是Desktop Heap已满。我在繁忙的大屏幕终端服务器上遇到过这个问题。

如果有大量文件句柄泄漏,您可以查看Process Explorer并查看流程的打开文件句柄,看看是否有任何异常。或者使用带有!htrace命令的WinDbg。

答案 2 :(得分:2)

我看到 EOutOfResources 的大部分时间都是某种句柄泄漏。

您是否尝试过类似 MadExcept 的内容?

- 的Jeroen

答案 3 :(得分:2)

“我试图输入一些调试代码来缩小问题范围。并且发现在保存文件时异常是EOutofResources。(文件保存每天可能发生数千次)。”< / p>

我在黑暗中拍摄,但可能是你正在使用Windows API(GetTempFileName)创建一个临时文件而你正在吹出一些文件系统索引或忘记关闭文件句柄?

无论哪种方式,我都同意你的假设是文件处理问题。鉴于您的症状和诊断,这似乎是最可能的事情。

答案 4 :(得分:2)

run into this problem before。根据我的判断,只要Windows API返回ERROR_NOT_ENOUGH_MEMORY,Delphi就可以抛出一个EOutOfResources,并且(如此处讨论的其他答案)Windows可能会针对各种条件返回ERROR_NOT_ENOUGH_MEMORY。

就我而言,EOutOfResources是由TBitmap引起的 - 特别是TBitmap对CreateCompatibleBitmap的调用,它与pfDevice的默认PixelFormat一起使用。显然,即使您的系统有足够的内存和大量的GDI资源,Windows也可能对可用于设备相关位图的内存强制实施相当严格的系统范围限制(例如,参见this discussion)。 (这些系统范围的限制显然是因为Windows可能会在视频卡的内存中分配与设备相关的位图。)

解决方案只是使用与设备无关的位图(DIB)(尽管这些可能无法提供相当好的性能)。要在Delphi中执行此操作,请将TBitmap.PixelFormat设置为除pfDevice之外的任何其他内容。 This KB article描述了如何为设备选择最佳DIB格式,尽管我通常只使用pf32Bit而不是尝试确定显示应用程序的每个监视器的最佳格式。

答案 5 :(得分:0)

还尝试使用SysInternals中的Process Explorer检查应用程序的句柄计数。处理泄漏可能非常危险,并且随着时间的推移它们会缓慢地形成。

答案 6 :(得分:0)

答案 7 :(得分:0)

我今天整天都在追踪这个问题。我发现了大量有用的资源将我引向了GDI的方向,事实是我正在使用GDI +通过timer / invalidate / onpaint(在单独的线程中执行动画)将高速动画直接制作到主窗体上。我也有这种形式的面板,其中包含一些动态创建的控件,供用户更改动画。

这是极端随机且自发的。它不会在我的代码中的任何位置中断,并且当出现错误对话框时,主窗体上的动画将继续起作用。某一时刻,其中两个错误同时弹出(与顺序错误相反)。

我仔细观察了我的代码,并确保我没有泄漏任何与GDI相关的句柄。实际上,根据任务管理器的说法,我的整个应用程序倾向于保留少于300个句柄。无论如何,此错误将随机弹出。而且,它总是与最简单的UI相关操作相对应,例如将鼠标移到标准VCL控件上。

解决方案

相信我已经解决了它,方法是更改​​逻辑以在自定义控件中执行绘图,而不是像以前那样直接更改为主要形式。我认为我正在快速在共享其他控件的相同表单画布上绘图的事实,以某种方式它们相互干扰。现在已经有了自己的专用画布,它似乎已经固定好了。

至少要进行约1小时的严格测试。

Animation Working Without Errors

[手指交叉]