`
blogfeifei
  • 浏览: 1197952 次
文章分类
社区版块
存档分类
最新评论

如何防止GDI资源泄露

 
阅读更多

在windows系列上做编程,gdi是一个很重要的技术点,有很多程序在运行多次后出现异常,除了众所周知的内存泄露以外,gdi资源泄露也是一个很直接的原因.今天就把我自己在编程中总结的一些经验给大家分享,欢迎高手补充.


1.Create出来的gdi对象,一定要用DeleteObject来释放,释放顺序是先Create的后释放,后Create的先释放.
这里的Create指的是以它为开头的gdi函数,比如,CreateDIBitmap,CreateFont等等,最后都要调用DeleteObject来释放.

2.Create出来的dc要用DeleteDC来释放,Get到的要用ReleaseDC释放.

3.确保释放DC的时候DC中的各gdi对象都不是你自己创建的;确保各gdi对象在释放的时候不被任何dc选中使用.


假如我们要使用gdi函数画图,正确的步骤应该如下:

a.创建一个内存兼容dc(CreateCompatibleDC)
b.创建一个内存兼容bitmap(CreateCompatibleBitmap)
c.关联创建的内存兼容dc和bitmap(SelectObject)
d.画图
e.BitBlt到目的dc上
f.断开内存兼容dc和bitmap关联(SelectObject)
g.销毁内存兼容bitmap
h.销毁内存兼容dc


由于SelectObject在选入一个新的gdi对象的时候会返回一个原来的gdi对象(假如成功的话),所以需要在步骤c的时候保存返回值,在步骤f的时候当作入口参数使用.还有,步骤g和步骤h实际上顺序可以随意,因为他们两个此刻已经没有关系了,但是为了结构清晰,我建议按照"先Create的后释放,后Create的先释放"的原则进行.
关于步骤f,可能会有争议,因为即使省略这一步,步骤g和步骤h看起来照样可以返回一个成功的值.但实际上可能并没有执行成功,至少boundschecker会报告有错,错误信息大致是说,在释放dc的时候还包含有非默认的gdi对象,在释放gdi对象的时候又说这个gdi对象还被一个dc在使用.所以,我建议保留步骤f.


对于CPen 来说,因为是CGdiObject的派生类,在析构函数中调用了DeleteObject()函数,所以不需要显式释放,CBrush 同理。但是如果CPen这里调用的是不带参数的构造函数的话,比如 CPen PenYellow; 这样的话后面必须还要调用CreatePen等函数来对CPen进行初始化工作,此时是需要显式释放的,即手动调用PenYellow.DeleteObject();

分享到:
评论
1 楼 hanjiangying 2012-05-03  
我觉得,关于步骤f,是否需要分两种情况:
1、这个DC里的当前图像不再使用,可以通过步骤f将其与DC断开连接,然后彻底销毁
2、如果这个DC里的当前图像在之后某个时刻还会用到,而且这个DC是全局变量,也可以不用步骤f,直接用步骤g销毁bitmap对象也是可以的,这样在DC中仍然保存有当前图像,当你最后销毁这个DC时,这残留的图像也会一起销毁

我在之前写一个图像显示的程序时,有一个背景图像要多次使用,为了避免每次用时都加载一次,我用了一个全局DC变量,只加载一次该图像,首次加载过程如下:
a.创建一个内存兼容dc(CreateCompatibleDC)
b.创建一个内存兼容bitmap(CreateCompatibleBitmap)
c.关联创建的内存兼容dc和bitmap(SelectObject)
d.加载背景图像
e.销毁内存兼容bitmap
f.销毁内存兼容dc
然后每次要用这个背景图像时,直接BitBlt图像到目的DC即可
这里没用到“断开内存兼容dc和bitmap关联(SelectObject)”这一步,经过步骤e之后,内存dc中的背景图像仍然存在,但是貌似步骤b创建的bitmap对象已经销毁了。程序运行过程中,通过任务管理器查看GDI对象和内存使用也没有增加

当这个内存DC不需要时,调用DeleteDC删除即可

相关推荐

    uilib gdi泄漏bug修复

    修复uilib库CControlUI类的gdi泄漏bug,原因在于构造函数创建gdi对象而一直未被释放

    GDI资源泄漏检测工具 GDI Leak Detector

    [English] I wrote this tool about 3 years ago. This tool can detect GDI object leak, and give the positon at source code where leak occured. ...它可以检测GDI对象泄漏,并能给出泄漏发生的源代码位置。

    GDI泄露检测工具

    一款很好用的Windows下GDI资源泄露检测工具,可以跟踪GDI资源的泄露情况。

    GDI 内存泄露检测工具

    windows客户端程序性能测试必须要验证资源泄漏,资源泄漏常见的测试项有:cpu/内存/GDI/句柄/页面错误增量

    c++编写的有GDI资源泄漏问题的文本框控件源码,求大神解决

    这是一个c++语言所编写的一个文本框控件源码,Node.ocx,但是该控件因未能及时释放GDI资源导致一直累加直到程序报错,望有能力的大神帮忙解决。

    GDI内存泄漏工具查看

    内存泄漏检测工具,可以查看未释放的GDI数量和USER对象的数量,方便开发人员释放应用程序的资源

    gdiLeak资源泄漏检测工具

    超强大的资源检测工具,可以实时跟踪程序使用的Bitmap, Brush,Pen,DC, MemDc,Font,Region,Palette等。并且能够显示具体的资源如: Bitmap:能显示内存中的Bitmap图像。 Brush: 画刷的颜色 。 。 。

    GDI泄露动态检查工具

    用于动态检查GDI资源泄露的工具,优于GDIUsage,为MSDN上 GDIndicator的增强版。

    GdiLeakDetector GDI资源及内存检测工具

    Windows下,资源检测工具,可以帮助查找内存和资源泄漏问题

    GDI检测工具.rar

    GDI检测工具,在mfc开发gdi程序时,监测gdi资源泄露

    GDI泄漏测试小工具

    一款实用的查看GDI资源泄漏的小工具,MFC编程有需要的可以用上。

    GDI 泄漏检测方法-附件资源

    GDI 泄漏检测方法-附件资源

    gdiview内存泄漏检测工具

    windows客户端程序性能测试必须要验证资源泄漏,资源泄漏常见的测试项有:cpu/内存/GDI/句柄/页面错误增量,今天的主题是GDI,测试GDI泄漏最简单最常用的工具是任务管理器,今天介绍的是另一个工具GDIView,GDIView...

    .NET资源泄露与处理方案知识点分享

    .NET虽然拥有强大易用的垃圾回收机制,但并不是因为这样,你就可以对资源管理放任不管,其实在稍不注意的时候,可能就造成了资源泄露,甚至因此导致系统崩溃,到那时再来排查问题就已经是困难重重。 一、知识点简单...

    世纪飞扬图形仪表 v5.1.zip

    世纪飞扬图形仪表ActiveX GDI 控件包括圆形仪表,线性仪表,旋钮,数码管,开关,趋势图等控件,完全基于GDI 技术,不同于传统的GDI界面,而是可以生成和.NET一样漂亮的图形,速度却大大...无内存泄漏,无资源泄漏;

    MFC SliderCtrl重绘

    重绘SliderCtrl 可以自行更改颜色大小等 修正了原本的GDI资源泄露问题

    GDIView检测工具

    windows客户端程序性能测试必须要验证资源泄漏,资源泄漏常见的测试项有:cpu/内存/GDI/句柄/页面错误增量,今天的主题是GDI,测试GDI泄漏最简单最常用的工具是任务管理器,今天介绍的是另一个工具GDIView,GDIView...

    飞鸽传书2.11稳定版本(VV纪念版)

    飞鸽传书(IPMsg)是一款跨平台的局域网即时通信软件;基于 TCP/IP(UDP) 协议; 无需服务器;支持文件及文件夹的传输,速度极快;十分小巧、操作简单、且完全... 修正发送对话框GDI资源泄漏 3. 修正不能添加4GB以上大文件

    1.1版 录像屏幕的指定区域并保存为多帧Gif图像 使用CxImage类 程序+源码

    前面那个1.0版上传后才发现有一个严重的GDI资源泄漏问题,于是火速上传此1.1版纠正此问题! 压缩包内“CxImageDemo.rar”是源码,“CxImageDemo.exe”是对应的Release版主程序,“截图6.0版.exe”是一个不相关的...

Global site tag (gtag.js) - Google Analytics