告诉你GetDC()没有释放造成的后果
最近做的项目中需要显示视频监控窗口,从采集卡中读到图像的数据,需要实时显示出来,而且速度比较快。
由于比较简单,就直接使用了GDI画图,以前复杂的都用openGL啥的工具了,这次这个简单,就直接用GDI了。
先获取DC,然后画图
pDC = this ->GetDC(); // 获得显示控件的 DC
this->GetClientRect(rect);
MemDC.CreateCompatibleDC(NULL);
//这时还不能绘图,因为没有地方画 ^_^
//下面建立一个与屏幕显示兼容的位图,至于位图的大小嘛,可以用窗口的大小
MemBitmap.CreateCompatibleBitmap(pDC,,);
pentemplate.CreatePen(PS_SOLID,,RGB(,,));
penkuang.CreatePen(PS_SOLID,,RGB(,,));
MemDC.SelectObject(&MemBitmap);
//printf("\n 拷贝图片");
StretchDIBits(MemDC.m_hDC, // 设备环境句柄
, //目标X坐标
, // 目标Y坐标
, // 目标宽度
, // 目标高度
, // 源X坐标
, // 源Y坐标
, // 源宽度
, // 源高度
ImageBuff, //图像数据指针BYTE*
&bmpInfo, // 指向位图信息结构的指针
DIB_RGB_COLORS, // 使用的颜色数目
SRCCOPY);
结束后进行释放内存DC和创建的画笔对象
pDC->BitBlt(,,,,&MemDC,,,SRCCOPY);
//printf("画图结束\n"); MemBitmap.DeleteObject();
penkuang.DeleteObject();
pentemplate.DeleteObject();
MemDC.DeleteDC();
注意,此时只对创建的内存DC和画笔对象进行了释放,对获取的pDC没有释放,这样短时间没什么问题,但是程序跑了几分钟以后,界面就没有反映了,整个界面卡死了,完全动不了。
这个问题困扰了我好几天,试了各种方法无果。
后来请教了一个朋友,朋友看到代码后,说pDC没有释放,我说GetDC需要释放吗,又不是new的。他说需要释放。
于是添加了
ReleaseDC(pDC);
重新跑下程序,跑了一天一也没有死。
但是问什么不释放会使程序界面卡死呢?于是对释放和不释放两个版本的程序进行观察。
启动任务管理器,把GDI对象添加到进程列中,观察两个版本的程序运行情况。程序名为OnlineFast

使用释放的版本,可以看到GDI对象保持157不变。
如果没有释放的话,GDI对象会一直增加


当然,此时程序还没有死,但运行一段时间后,当GDI对象增加到10000的时候,程序就死了,这就是GDI对象的极限了。
所以,GetDC 和ReleaseDC一定要配对使用,获取了,没有去释放,windows不会自动去释放,一直占用这,直到到达极限,资源耗尽,程序就崩溃了。
照例贴上俩儿子的照片,又离家一个月了,一个月没见到俩儿子了。

告诉你GetDC()没有释放造成的后果的更多相关文章
- C++—复合类型
内容概要: -创建和使用数组 -创建和使用C-风格字符串 -创建和使用string类字符串 -使用方法getline()和get()读取字符串 -混合输入字符串和数字 -创建和使用结构 -创建和使用共 ...
- C++_基础2-复合数据类型
C语言使用术语“派生类型”,C++对类关系使用术语“派生”.所以就改用“复合类型”. 数组 数组是一种数据格式,能够存储多个同类型的值. 数组声明应指出以下三点: 存储在每个元素中的值的类型: 数组名 ...
- 我的MFC/C++学习笔记 http://blog.bccn.net/CrystalFan/6909
2009.07.31 ------------------------------------------------------------------------------------ No.1 ...
- Android APP性能分析方法及工具
近期读到<Speed up your app>一文.这是一篇关于Android APP性能分析.优化的文章.在这篇文章中,作者介绍他的APP分析优化规则.使用的工具和方法.我觉得值得大家借 ...
- WWDC 2013 Session笔记 - UIKit Dynamics入门
本文涉及到的WWDC2013 Session有 1.Session 206 Getting Started with UIKit Dynamics 2.Session 221 Advanced Tec ...
- lnux下源码安装MySQL 5.6
nux下源码安装MySQL 5.6 说明:本文是我自己测试的MySQL5.6源码安装,经本人亲自实践,完全可用,另在5.6之前的版本也是可以按照本文源码安装的.我是在两台linux下一台安装5.5,另 ...
- 查找文件是否安装以及安装路径(Ubuntu 下 )
参考:<linux下如何查看某个软件 是否安装??? 安装路径在哪???> 原文: 如果你使用rpm -ivh matlab装的, 用rpm -qa | grep matlab肯定是能够找 ...
- 深入理解C语言中的指针与数组之指针篇
转载于http://blog.csdn.net/hinyunsin/article/details/6662851 前言 其实很早就想要写一篇关于指针和数组的文章,毕竟可以认为这是C语言的根本 ...
- c# 数据库操作学习
一. 如何处理数据库连接 1. 数据库连接可以分为“物理连接”和“逻辑连接”(默认使用连接池的情况下Pooling=true): 物理连接:创建数据库连接时,默认会有一定数量的物理连接(默认Min P ...
随机推荐
- Scut:Redis 资源管理器
核心文件是:RedisConnectionPool.cs 对象池类的通用泛型封装:ObjectPoolWithExpire<T> 1. 主要变量 private static ICache ...
- Keil使用中的若干问题
一.混合编程 1.模块内接口: 使用如下标志符: #pragma asm 汇编语句 #pragma endasm 注意:如果在c51程序中使用了汇编语言,注意在keil编译器中需要激活Properti ...
- linux下svn修改用户名和密码
1.临时更换,在命令下强制加上 --username 和--password选项, 例如:svn up --username zhangsan --password 123456 svn co URL ...
- ISNULL-sqlserver语句
语法 ISNULL ( check_expression , replacement_value ) 参数 check_expression 将被检查是否为 NULL的表达式.check_expres ...
- Java中Websocket使用实例解读
介绍 现在很多网站为了实现即时通讯,所用的技术都是轮询(polling).轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP request,然后由服务器返回最新的数据给客服端的浏览器 ...
- mybatis3-generator-plugin插件地址
http://repo1.maven.org/maven2/com/github/oceanc/mybatis3-generator-plugin/0.4.0/
- J - Assign the task - hdu 3974(DFS建树+简单线段树)
题意:给一些节点简单额对应关系,可以组成一个树,如果树的某一个节点更新那么他的所有子节点都要更新,中间,会有一些查询 分析:题意倒也不难理解,但是但是不知道怎么建树...于是自能百度,看了kuangb ...
- Vagrant 部署python开发环境
Vagrant简介 Vagrant是一个基于Ruby的工具,用于创建和部署虚拟化开发环境.它使用Oracle的开源VirtualBox虚拟化系统,使用 Chef创建自动化虚拟环境. 在Windows下 ...
- VS2010每次编译都重新编译整个工程的解决方案
在使用VS2010编译C++程序的时候,每次修改工程中的某一个文件,点击“生成-仅用于项目-仅生成**”时,往往都是整个工程都需要重新编译一遍.由于这个工程代码量太大,每次编译完成都需要将近10分 ...
- Shell脚本:判断用户和用户组是否已经存在/创建用户和用户组
通常作为一个应用程序的部署脚本,开始的第一项工作是为当前应用创建一个专用(dedicated)的用户和用户组.这个脚本很简单,这里贴一个参考样本: #!/bin/sh user=test_user ...