出错现象:
在同一台电脑上同时运行该应用程序的三个实例,经过两天后,其中的一个实例出现以下问题:
1、主对话框的菜单项变成黑方框,标题栏消失(偶尔),需要鼠标移动后才能显示。
2、对话框控件内容消失。
3、非模态对话框能够打开,模态对话框无法打开。
4、对话框资源不在dll内。
5、正常工作的实例占用内存4M左右,出现异常的实例占用内存不到2M;电脑物理内存512M,工作时,内存占用为630/1024。
找了两天,得到的答案是:
应该是GDI资源释放的问题,例如你使用了CPen, CBrush等,一定要调用x.DeleteObject(),如果使用了new指针也要及时释放。对方运行多个程序才会出现此问题,更加佐证了GDI问题,多个程序切换会导致你的主程序刷新界面,而你的主程序重绘,又要消耗GDI资源。如果只运行你的程序,界面刷新的情况很少甚至没有。
开始的时候没有理解怎样才算做GDI资源泄漏。根据上面回答,对程序中所有使用CPen、CBrush和CDC的地方都进行了排查和修改,仍然存在问题。
内存泄漏的情况是很容易通过进程所占用内存的大小来判断的,如何才能检测GDI资源泄漏呢?
在论坛里发帖咨询后,得到的答案仍然是GDI资源泄漏,所幸的是知道如何去查看GDI资源数量了。即,在“任务管理器”-“查看”-“选择列”中选中“GDI对象”,即可看到各个进程的GDI数量,从而判断程序是否存在GDI资源泄漏的问题。
再次排查时,我发现每打开一个带背景色的对话框都会导致GDI资源数量增加,突然想到OnCtrlColor里返回的画刷的句柄因为是局部变量而没有被释放。改为成员变量,在构造函数中创建画刷,在析构函数中释放画刷资源,问题就这样解决了。