分享下自己工作中用到的一些用于泄漏检测的工具

后面的是DC的一些定义和注意事项。(不喜勿看)

//===========================================================

GDI对象和Handle对象泄漏检测

http://www.nirsoft.net/utils/gdi_handles.html

http://www.nirsoft.net/utils/gdiview-x64.zip

GDIView

Web site: http://www.nirsoft.net

可以看到我画圈的地方是Handle对象的指针,找到对象指针,

你只要在分配的时候加上相应的log,那么运行的时候,跑各种IF,每个GDI对象指针都知道在哪,什么时候分配和释放。(不是很方便,但是能用)

这是我在http://www.filebuzz.com/files/Handle_Leak/freeware-1.html找到的,还有Handle Tracer等等

分割线

//===========================================================

Handle泄漏
ProcessExplorer
http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx

https://docs.microsoft.com/en-us/sysinternals/downloads/process-explorer

可以代替任务管理器,轻松找到各种handle, (thread, Section ,Semaphore,Timer,  Event, File, IOComPletion, Key......基本上包括了所有的Handle类型)

功能太多,就不一一列举

参见图

分割线

//===========================================================

对于内存泄漏检查  参考

http://www.zhihu.com/question/19647750

http://stackoverflow.com/questions/413477/is-there-a-good-valgrind-substitute-for-windows

之前只用过DevPartner

 分割线

//================================================================

1.CDC类 的定义

http://msdn.microsoft.com/zh-cn/library/vstudio/fxhhde73.aspx
HDC GetDC(   _In_  HWND hWnd );
http://msdn.microsoft.com/en-us/library/dd144871%28v=vs.85%29.aspx 

Remarks

The GetDC function retrieves a common, class, or private DC depending on the class style of the specified window. For class and private DCs, GetDC leaves the previously assigned attributes unchanged. However, for common DCs, GetDC assigns default attributes to the DC each time it is retrieved. For example, the default font is System, which is a bitmap font. Because of this, the handle to a common DC returned by GetDC does not tell you what font, color, or brush was used when the window was drawn. To determine the font, call GetTextFace.

Note that the handle to the DC can only be used by a single thread at any one time.

After painting with a common DC, the ReleaseDC function must be called to release the DC. Class and private DCs do not have to be released. ReleaseDC must be called from the same thread that called GetDC. The number of DCs is limited only by available memory.

int ReleaseDC(   _In_  HWND hWnd,   _In_  HDC hDC );
http://msdn.microsoft.com/en-us/library/dd162920%28v=vs.85%29.aspx
Remarks

The application must call the ReleaseDC function for each call to the GetWindowDC function and for each call to the GetDC function that retrieves a common DC.

An application cannot use the ReleaseDC function to release a DC that was created by calling the CreateDC function; instead, it must use the DeleteDC function. ReleaseDC must be called from the same thread that called GetDC.


GetDC()之后一定要ReleaseDC().
CreateDC()之后一定要DeleteDC(). GDI对象,Handle句柄,和线程数,内存,fd,一样都有限制。
现工程就因为画图,DC 未释放,导致了crash~~~最后还要遍地找泄漏,还是不要维护代码的好。(本人一向喜欢break to build) Sample:
http://msdn.microsoft.com/en-us/library/dd162950%28v=vs.85%29.aspx
CDC::Attach 后要 CDC::Detach
分割线

//=====================================

再转下别人写的Blog,自己保留一下

http://blog.sina.com.cn/s/blog_447611f20100lirt.html
首先说一下什么是DC(设备描述表)
解:Windows应用程序通过为指定设备(屏幕,打印机等)创建一个设备描述表(Device Context, DC)在DC表示的逻辑意义的“画布”上进行图形的绘制。DC是一种包含设备信息的数据结构,它包含了物理设备所需的各种状态信息

。Win32程序在绘制图形之前需要获取DC的句柄HDC,并在不继续使用时释放掉。

在c 编程中常会见到HDC,CDC,CClientDC,CPaintDC,CWindowDC这样的类
HDC是DC的句柄,API中的一个类似指针的数据类型.
CDC是MFC的DC的一个类
CDC等设备上下分类,都含有一个类的成员变量:m_nHdc;即HDC类型的句柄.

CDC及其派生类的继承视图:
CObject
public |------CDC
public |------|------CClientDC
public |------|------CPaintDC
public |------|------CWindowDC
public |------|------CMetaFileDC
(注意: 除CMetaFileDC以外的三个派生类用于图形绘制.)

CDC类定义了一个设备描述表相关的类,其对象提供成员函数操作设备描述表进行工作,如显示器,打印机,以及显示器描述表相关的窗口客户区域。

通过CDC的成员函数可进行一切绘图操作。CDC提供成员函数进行设备描述表的基本操作,使用绘图工具,选择类型安全的图形设备结构(GDI),以及色 彩,调色板。除此之外还提供成员函数获取和设置绘图属性,映射,控制视口,窗体范围,转换坐标,区域操作,裁减,划线以及绘制简单图形(椭圆,多边形 等)。成员函数也提供绘制文本,设置字体,打印机换码,滚动,处理元文件。

其派生类:
1.PaintDC: 封装BeginPaint和EndPaint两个API的调用。
(1)用于响应窗口重绘消息(WM_PAINT)是的绘图输出。
(2)CPaintDC在构造函数中调用BeginPaint()取得设备上下文,在析构函数中调用EndPaint()释放设备上下文。 EndPaint()除了释放设备上下文外,还负责从消息队列中清除WM_PAINT消息。因此,在处理窗口重画时,必须使用CPaintDC,否则 WM_PAINT消息无法从消息队列中清除,将引起不断的窗口重画。
(3)CPaintDC也只能用在WM_PAINT消息处理之中。

2.CClientDC(客户区设备上下文): 处理显示器描述表的相关的窗体客户区域。
用于客户区的输出,与特定窗口关联,可以让开发者访问目标窗口中客户区,其构造函数中包含了GetDC,析构函数中包含了ReleaseDC。

3.CWindowDC: 处理显示器描述表相关的整个窗体区域,包括了框架和控 件(子窗体)。
(1)可在非客户区绘制图形,而CClientDC,CPaintDC只能在客户区绘制图形。
(2)坐标原点是在屏幕的左上角,CClientDC,CPaintDC下坐标原点是在客户区的左上角。
(3)关联一特定窗口,允许开发者在目标窗口的任何一部分进行绘图,包含边界与标题,这种DC同WM_NCPAINT消息一起发送。

4.CMetaFileDC: 与元文件相关的设备描述表关联。

CDC提供两个函数,GetLayout和SetLayout用于反转设备描述表的布局。用于方便阿拉伯,希伯来的书写文化习惯的设计,以及非欧洲表中的字体布局。

CDC包含两个设备描述表,m_hDC和m_hAttribDC对应于相同的设备,CDC为m_hDC指定所有的输出GDI调用,大多数的GDI属性调用 由m_hAttribDC控制。(如,GetTextColor是属性调用,而SetTextColor是一种输出调用。)

下面用一些简单的代码看看如果使用这些类
HDC使用, 每次画线等操作都不MFC封装的类多了个HDC的参数
执行在哪个设备描述表操作
HDC hdc=::GetDC(m_hWnd);//m_hWnd == this->m_hWnd 即当前窗口句柄
MoveToEx(hdc,m_ptOrigin.x,m_ptOrigin.y,NULL);
LineTo(hdc,point.x,point.y);
::ReleaseDC(m_hWnd,hdc);//必须和GetDC配对
可以看到HDC的使用较麻烦, 而且如果::GetDC和::ReleaseDC不配对的话,会造成错误

CDC *pDC=GetDC();
pDC->MoveTo(m_ptOrigin);
pDC->LineTo(point);
ReleaseDC(pDC);

CClientDC dc(this);
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);

CWindowDC dc(this);
CWindowDC dc2(GetDesktopWindow());//获得整个桌面的句柄, 一些桌面特效程序使用
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);

CPaintDC dc(this);
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);

可以看到 MFC 的类使用方便很多, 因为它们都在构造函数和析构函数调用了响应的函数进行DC的获取和释放.

下面说下一些细点的知识点
CClientDC,CWindowDC 区别不大, 可以说 CWindowDC包含了CClientDC 就拿记事本来说
CClientDC 就只是白白的我们可以编辑文字的那个区域是 客户区
CWindowDC 除了上面说的白白区域, 还包括菜单栏和工具栏等

CClientDC和CWindowDC 与 CPaintDC 的区别大点
在DC的获取方面 CClientDC和CWindowDC 使用的是并只能是 GetDC 和 ReleaseDC
CPaintDC 使用的是并只能是 BeginPaint 和 EndPaint

CPaintDC 只能用在响应 WM_PAINT 事件
CClientDC,CWindowDC 只能用在响应 非WM_PAINT 事件

关于 WM_PAINT 事件
系统会在多个不同的时机发送WM_PAINT消息:当第一次创建一个窗口时,当改变窗口的大小时,当把窗口从另一个窗口背后移出时,当最大化或最小化窗口 时,等等,这些动作都是由系统管理的,应用只是被动地接收该消息,在消息处理函数中进行绘制操作;大多数的时候应用也需要能够主动引发窗口中的绘制操作, 比如当窗口显示的数据改变的时候,这一般是通过InvalidateRect和InvalidateRgn函数来完成的。InvalidateRect和 InvalidateRgn把指定的区域加到窗口的Update Region中,当应用的消息队列没有其他消息时,如果窗口的Update Region不为空时,系统就会自动产生WM_PAINT消息。

系统为什么不在调用Invalidate时发送WM_PAINT消息呢?又为什么非要等应用消息队列为空时才发送WM_PAINT消息呢?这是因为系统把 在窗口中的绘制操作当作一种低优先级的操作,于是尽可能地推后做。不过这样也有利于提高绘制的效率:两个WM_PAINT消息之间通过 InvalidateRect和InvaliateRgn使之失效的区域就会被累加起来,然后在一个WM_PAINT消息中一次得到更新,不仅能避免多次 重复地更新同一区域,也优化了应用的更新操作。像这种通过InvalidateRect和InvalidateRgn来使窗口区域无效,依赖于系统在合适 的时机发送WM_PAINT消息的机制实际上是一种异步工作方式,也就是说,在无效化窗口区域和发送WM_PAINT消息之间是有延迟的;有时候这种延迟 并不是我们希望的,这时我们当然可以在无效化窗口区域后利用SendMessage 发送一条WM_PAINT消息来强制立即重画,但不如使用Windows GDI为我们提供的更方便和强大的函数:UpdateWindow和RedrawWindow。UpdateWindow会检查窗口的Update Region,当其不为空时才发送WM_PAINT消息;RedrawWindow则给我们更多的控制:是否重画非客户区和背景,是否总是发送 WM_PAINT消息而不管Update Region是否为空等。

http://blog.csdn.net/a379039233/article/details/46501757

https://msdn.microsoft.com/zh-cn/library/kt7c0708.aspx

modalless 窗口类

声明

DECLARE_DYNAMIC

https://msdn.microsoft.com/zh-cn/library/ywz9k63y.aspx

Adds the ability to access run-time information about an object's class when deriving a class from CObject.

IMPLEMENT_DYNAMIC

https://msdn.microsoft.com/zh-cn/library/es8sbsx5.aspx

Generates the C++ code necessary for a dynamic CObject-derived class with run-time access to the class name and position within the hierarchy.

生成一些代码,使窗口动态对象子类,访问继承父类的析构。

VC一些经验系列: 《分享泄漏检测工具:内存、DC、GDI、Handle... 》的更多相关文章

  1. android 内存泄漏检测工具 LeakCanary 泄漏金丝雀

    韩梦飞沙 yue31313 韩亚飞 han_meng_fei_sha 313134555@qq.com 内存泄漏检测工具 android 内存泄漏检测工具 ======== 内存泄漏 就是  无用的对 ...

  2. Cocos开发中性能优化工具介绍之Visual Studio内存泄漏检测工具——Visual Leak Detector

    那么在Windows下有什么好的内存泄漏检测工具呢?微软提供Visual Studio开发工具本身没有什么太好的内存泄漏检测功能,我们可以使用第三方工具Visual Leak Detector(以下简 ...

  3. C++内存泄漏检测工具

    C++内存泄漏检测工具 1.VC自带的CRT:_CrtCheckMemory   调试器和 CRT 调试堆函数 1.1用法: /************************************ ...

  4. C/C++的内存泄漏检测工具Valgrind memcheck的使用经历

    Linux下的Valgrind真是利器啊(不知道Valgrind的请自觉查看参考文献(1)(2)),帮我找出了不少C++中的内存管理错误,前一阵子还在纠结为什么VS 2013下运行良好的程序到了Lin ...

  5. Android 性能优化之内存泄漏检测以及内存优化(中)

    https://blog.csdn.net/self_study/article/details/66969064 上篇博客我们写到了 Java/Android 内存的分配以及相关 GC 的详细分析, ...

  6. 内存泄漏检测工具VLD在VS2010中的使用举例

    Visual LeakDetector(VLD)是一款用于Visual C++的免费的内存泄露检测工具.它的特点有:(1).它是免费开源的,采用LGPL协议:(2).它可以得到内存泄露点的调用堆栈,可 ...

  7. 内存泄漏检测工具Valgrind

    1概述 1.1 介绍 Valgrind是一套Linux下,开放源代码(GPL V2)的仿真调试工具的集合.Valgrind由内核(core)以及基于内核的其他调试工具组成.内核类似于一个框架(fram ...

  8. Cocos性能优化工具的开发介绍Visual Studio内存泄漏检测工具——Visual Leak Detector

    然后,Windows下有什么好的内存泄漏检測工具呢?微软提供Visual Studio开发工具本身没有什么太好的内存泄漏检測功能.我们能够使用第三方工具Visual Leak Detector(下面简 ...

  9. 【转】Unix下C程序内存泄漏检测工具Valgrind安装与使用

    Valgrind是一款用于内存调试.内存泄漏检测以及性能分析的软件开发工具. Valgrind的最初作者是Julian Seward,他于2006年由于在开发Valgrind上的工作获得了第二届Goo ...

随机推荐

  1. HDOJ(1000) A + B Problem

    代码如下: #include <stdio.h> int main(void) { int a, b; ){ printf("%d\n", a+b); } ; }

  2. Linux EMACS的简单使用

    1 File 菜单项 open file 打开文件 close 关闭当前操作的文件 save 保存当前操作的文件 save buffer as 另存为 split window 拆分窗口 ,同时操作不 ...

  3. NUnit单元测试

    单元测试对程序员来说是非常重要的一门技术,但是在实际编程中却往往被程序员所忽视.微软的VS开发工具为我们提供了强大的单元测试环境,在VS当中可以直接对类库项目进行测试,极大的方便了程序员的自我纠错能力 ...

  4. 002.TPerlRegEx简单测试

    我要做什么? 将一个字符串中的所有连续的数字替换成一个* 代码: program Project1; {$APPTYPE CONSOLE} uses System.SysUtils, PerlRegE ...

  5. leetcode解题—Longest Palindromic Substring

    题目: Given a string S, find the longest palindromic substring in S. You may assume that the maximum l ...

  6. lua中的时间函数

    -- 获取当前的格林尼治时间print(os.time())-- 获取当前时间的字符串表示,形如:11/28/08 10:28:37print(os.date())-- 获取当前日期的字符串表示,形如 ...

  7. Oracle 排序分析函数之ROW_NUMBER、RANK和DENSE_RANK

    我们都知道分析函数功能很强大,可能需要写很复杂的标准SQL才能办到或不可能办到的事,使用分析函数却能很容易完成.我们经常会用到排序分析函数,如ROW_NUMBER,RANK,DENSE_RANK.这三 ...

  8. cocos2dx输出信息重定向到控制台

    重定向输出到控制台,方便调试,代码: // uncomment below line, open debug console #define USE_WIN32_CONSOLE int APIENTR ...

  9. 【Selenium】自动化调试后C盘越来越大

    在本机调试了一段时间自动化脚本后发现C盘占用越来越大,增长速度比较明显 通过360等工具清理系统垃圾表明并不好使 最后在系统临时文件中看到大量因为调试或不正常结束而Driver而产生的临时文件 具体方 ...

  10. c++函数内部可以返回函数内部定义的指针 但是不能返回函数内部定义的数组

    1.返回数组 // demo.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<stdio.h> char *m ...