”无法找到所需的资源“——GDI绘图相关——MFC运行异常
作者:互联网
这两天用程序时碰到神奇的问题,软件短时间运行OK,但一定时间后(6个小时及以上),界面刷新失败,对软件长时间不处理后,软件自动退出。以前软件因堆内存耗尽退出的都会产生dmp文件,根据这个比较好定位问题。但是此次的软件退出,有时并不会产生dmp文件,有时虽然会有dmp文件,但调用堆栈都停止在系统级DLL调用,和软件本身好像并没有关系,使我也不知道问题到底出在什么地方。
停止的调用堆栈在GDI32.dll,结合以前看到的,无非就是DC之类的没释放呗。想过几种可能的情况,
- 本身就未释放DC
- 申请了DC,但在不合适的地方提前返回,导致DC未及时回收
- 公共库自身问题
逐一排查呗,都试了,无果,直到今天早上弹了个窗“无法找到所需的资源”,一搜,可算定位到问题的位置!
在使用CFont字体使,调用了CreateFont(...),但并未及时调用DeleteObject(),使GDI资源一直未回收,爆炸!!!
查看了MSDN关于CFont的继承关系,大致如下,父类中有一个是CGdiObject,emmm,申请了不释放,不爆炸才怪,不过MSDN说明文档里也并没有写清楚。
class CFont: public CObject, public CGdiObject
{
//...
};
写了一个小程序用来处理数据,用到了MFC框架来显示界面。当程序运行时间较短时没有问题,当程序长时间运行时出现了莫名其妙的崩溃。直到有一次弹出了对话框提示“无法找到所需的资源”。
同时之前有注意到程序运行到GetDC()处停止过,再结合这篇文章告诉你GetDC()没有释放造成的后果找到了问题所在。
原来是因为在调用GetDC()获取句柄之后,没有及时释放,导致了程序占用了超多的GDI对象,如下图所示:
在代码中及时调用ReleaseDC(pDC)之后,GDI对象数量就稳定在一个低水平了:
小结
- GDI对象、DC对象属于系统资源,数量有限,不能无限调用
- 调试工具的使用——任务管理器中查看GDI对象等其他信息
- 需要更进一步了解计算机原理、操作系统相关知识。
标签:MSDN,MFC,CFont,DC,调用,绘图,软件,GDI 来源: https://blog.csdn.net/VVBBBBB/article/details/100151826