利用任务管理器侦测GDI内存泄露


        打开任务管理器,点击菜单“查看”——“选择列”,勾上所有项,“确定”。运行自己的程序,进行各种操作,并查看任务管理器中GDI对象和句柄数的变化。

        如果在某次可逆操作中,例如,弹出一个对话框,然后关闭,GDI对象或句柄数先增加了,然后减少了,但是总量还是增加了,说明存在内存泄露,GDI对象没有被及时回收。如果句柄数出现类似情况,则情况复杂很多。

        接下来,注释掉某些代码,编译运行并继续观察,逐步定位导致内存泄露的代码段。

 

        实例:

        某程序运行时,弹出一个窗口,再关闭,GDI对象数目就增加了一个。经过一个多小时的分析,最后定位出问题所在,如下:

        LOGFONT logfont={0};

        GetObject(m_font, sizeof(logfont), &logfont);

        logfont.lfHeight = -MulDiv(size, GetDeviceCaps(::GetDC(NULL), LOGPIXELSY), 72);

        SetFont(&logfont);

        这段代码是用来改变窗口的字体大小的,size是字体的磅数,但是LOGFONT是按像素计算字体大小的,所以,需要转换字体的磅数为像素大小。这里只转换了高度,因为设置字体大小时,只需要高度就可以了。 logfont.lfHeight = -MulDiv(size, GetDeviceCaps(::GetDC(NULL), LOGPIXELSY), 72);  这句代码是从网上搜索到的、转换字体磅数为像素大小的代码,我也没有去细看,直接copy了一下,毕竟代码很短,乍一看,真没什么问题。然而,这里使用了GetDC,这将导致GDI对象增加,所以,应该调用DeleteDC回收,这就是问题所在。

修改后的代码为:

 LOGFONT logfont={0};

 GetObject(m_font, sizeof(logfont), &logfont);

 HDC hdc=::GetDC(NULL);

 ASSERT(hdc!=NULL);

 logfont.lfHeight = -MulDiv(size, GetDeviceCaps(hdc, LOGPIXELSY), 72);

 ::DeleteDC(hdc);

 SetFont(&logfont);

 
注:

其实这里应该是::ReleaseDC(NULL, hdc);而不是DeleteDC,具体请查阅MSDN。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值