zoukankan      html  css  js  c++  java
  • GDI泄漏排查经验零散总结

    1.GDI对象以及释放方法:

    GDI对象

    产生方法

    销毁方法

    位图(HBITMAP)

    CreateBitmap,CreateBitmapIndirect,

    CreateCompatibleBitmap,CreateDIBitmap,

    CreateDIBSection,CreateDiscardableBitmap

    DeleteObject

    画刷(HBRUSH)

    CreateBrushIndirect,CreateDIBPatternBrush,

    CreateDIBPatternBrushPt,CreateHatchBrush,

    CreatePatternBrush,CreateSolidBrush

    DeleteObject

    设备上下文(HDC)

    CreateDC

    DeleteDC,ReleaseDC

    字体(HFONT)

    CreateFont,CreateFontIndirect

    DeleteObject

    内存DC(HDC)

    CreateCompatibleDC

    DeleteDC

    调色板(HPALETTE)

    CreatePalette

    DeleteObject

    画笔(HPEN)

    CreatePen,CreatePenIndirect

    DeleteObject

    区域(HRGN)

    CombineRgn,CreateEllipticRgn,

    CreateEllipticRgnIndirect,CreatePolygonRgn,

    CreatePolyPolygonRgn,CreateRectRgn,

    CreateRectRgnIndirect,CreateRoundRectRgn,

    DeleteObject

    2.资源切换时容易出现的GDI泄漏:

    1)SelectObject、SetBitmap、SetIcon、SendMessage(消息为BM_Bitmap时),会返回之前使用的GDI资源,不再使用的GDI资源需要及时释放(记录好之前使用的系统GDI资源,在结束时还原设置并释放掉申请的GDI资源);

    2)SelectObject 选入的用户创建的GDI资源,需要在不再使用时选出并释放。

    3)使用的控件有时候会因为一些原因在Res资源中添加过图标等GDI资源,导致在代码中做控件初始化时设置新图标产生了GDI泄漏(从代码上来看是第一次设置图标就引起了泄漏)。

    4) ::GetDC使用::ReleaseDC来释放,CreateDC CreateCompatibleDC使用DeleteDC来释放。

    5)窗体Hwnd没有释放也会引起GDI泄漏,因为窗体中使用的GDI资源没有销毁时机,自然也就调用不到内部的销毁函数。

    3.LoadImage函数:

    LoadImage函数可以加载Bitmap、Icon、Cursor三种GDI资源,需要分别使用DeleteObject、DestroyIcon、DestroyCursor来释放,不可以混用。

    LoadImage函数生成的GDI资源使用后就可以释放,不会因为立即释放后导致前面设置的资源不起作用。

    4. CImageList存储的GDI资源需要调用DeleteImageList来释放。

    5.CDC、CPEN、CBrush等MFC包装的GDI类,在其析构函数中会调用DeleteObject函数取释放资源。

    6.创建GDI资源的函数和释放GDI的函数使用次数要匹配,比如:窗口Create、OnInitDialog、以及消息响应等函数会因为一些原因多次调用(比如DoModal如果被循环调用是会引起窗口的Create和OnInitDialog反复触发),如果在这类函数中申请GDI资源需要特别注意,因为一般作为成员变量的GDI资源的释放在析构函数中的话就只会被调用一次。

    7.给外部模块调用的函数中如果包含了GDI资源的申请需要在函数头注释,提醒调用者需要手动释放(往往函数被包装几层后外层函数调用者很容易忽略释放)。

    8.少量代码是可以根据代码静态检视或者分模块调试来找出GDI泄漏位置,但是大量代码排查需要借助工具才比较有效率,这里推荐Deleaker这款工具(GDI泄漏和内存泄漏都可以准确的找出代码行)。

  • 相关阅读:
    一个简单的PHP登录演示(SESSION版 与 COOKIE版)
    web系统之session劫持解决
    CKFinder 1.4.3 任意文件上传漏洞
    linux服务器磁盘扩容的方法
    Linux下lvm在线扩容步骤
    Centos7使用LVM扩容磁盘(测试成功)
    CentOS7下利用init.d启动脚本实现tomcat开机自启动
    Linux tomcat安装详解(未完)
    linux下 目录(扩容)挂载磁盘
    Linux下环境变量设置
  • 原文地址:https://www.cnblogs.com/lmst-ytt/p/12987445.html
Copyright © 2011-2022 走看看