LoadBitmap返回的HBITMAP未删除导致的内存泄漏问题
2011-09-27 17:42
369 查看
最近写程序检查某个工程的内存泄漏问题,检查很久,修修补补,也补了部分内存泄漏问题,但是在画界面部分还是存在内存泄漏,而且经常间歇性才发作,百思不得其解,找了很多资料无果,只能自己一句句代码查找,功夫不负有心人最后让我发现了。。。
原来有内存泄漏的代码:
void CWinXXXDlg::OnPaint()
{
CDC dcMem;
CBitmap bmpMem;
BITMAP bm2;
CBitmap *pOldBm2=NULL;
dcMem.CreateCompatibleDC(&dc);
bmpMem.CreateCompatibleBitmap(&dc,800,480);
CBitmap *pOldBm=dcMem.SelectObject(&bmpMem);
CDC dcMem2;
dcMem2.CreateCompatibleDC(&dcMem);
CBitmap bmpMem2;
bmpMem2.Attach(::LoadBitmap( AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP_BACKGROUND))); //背景
bmpMem2.GetBitmap(&bm2);
pOldBm2=dcMem2.SelectObject(&bmpMem2);//选BITMAP
dcMem.BitBlt(0,0,800,480,&dcMem2,0,0,SRCCOPY); //画背景位图
dcMem2.SelectObject(pOldBm2);//选回旧的bitmap进行清理内存
bmpMem2.Detach();
dcMem.SelectObject(pOldBm);//选回旧的bitmap进行清理
bmpMem.DeleteObject();
bmpMem2.DeleteObject();
dcMem.DeleteDC();
dcMem2.DeleteDC();
}
咋一看,好像没什么问题。
这程序在Timer中每100ms 运行一次this->Invalidate(0),我测试的WINCE 6中运行一直内存稳定,但是到了1个小时左右内存会迅速以4KB的速度一直减少
一直想不明白,最后发现原来是LoadBitmap惹的祸。
原程序中为了方便,将Attach和LoadBitmap写在了一条语句,但是LoadBitmap会返回一个HBITMAP的GDI句柄,MSDN中说到:
The application must call the DeleteObject function to delete each bitmap handle returned by the LoadBitmap function.
就是因为写在了一条语句上,所以忽略了它的返回值,导致有句柄没有删除引起内存泄漏。
原因知道了,下面改写代码:
void CWinXXXDlg::OnPaint()
{
CDC dcMem;
CBitmap bmpMem;
BITMAP bm2;
CBitmap *pOldBm2=NULL;
dcMem.CreateCompatibleDC(&dc);
bmpMem.CreateCompatibleBitmap(&dc,800,480);
CBitmap *pOldBm=dcMem.SelectObject(&bmpMem);
CDC dcMem2;
dcMem2.CreateCompatibleDC(&dcMem);
CBitmap bmpMem2;
HBITMAP hbitmap=::LoadBitmap( AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP_BACKGROUND));//改成返回hbitmap
bmpMem2.Attach(hbitmap); //通过句柄进行Attach背景
bmpMem2.GetBitmap(&bm2);
pOldBm2=dcMem2.SelectObject(&bmpMem2);//选BITMAP
dcMem.BitBlt(0,0,800,480,&dcMem2,0,0,SRCCOPY); //画背景位图
dcMem2.SelectObject(pOldBm2);//选回旧的bitmap进行清理内存
DeleteObject(hbitmap);//最后还要使用这个删除HBITMAP句柄
bmpMem2.Detach();
dcMem.SelectObject(pOldBm);//选回旧的bitmap进行清理
bmpMem.DeleteObject();
bmpMem2.DeleteObject();
dcMem.DeleteDC();
dcMem2.DeleteDC();
}
原来有内存泄漏的代码:
void CWinXXXDlg::OnPaint()
{
CDC dcMem;
CBitmap bmpMem;
BITMAP bm2;
CBitmap *pOldBm2=NULL;
dcMem.CreateCompatibleDC(&dc);
bmpMem.CreateCompatibleBitmap(&dc,800,480);
CBitmap *pOldBm=dcMem.SelectObject(&bmpMem);
CDC dcMem2;
dcMem2.CreateCompatibleDC(&dcMem);
CBitmap bmpMem2;
bmpMem2.Attach(::LoadBitmap( AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP_BACKGROUND))); //背景
bmpMem2.GetBitmap(&bm2);
pOldBm2=dcMem2.SelectObject(&bmpMem2);//选BITMAP
dcMem.BitBlt(0,0,800,480,&dcMem2,0,0,SRCCOPY); //画背景位图
dcMem2.SelectObject(pOldBm2);//选回旧的bitmap进行清理内存
bmpMem2.Detach();
dcMem.SelectObject(pOldBm);//选回旧的bitmap进行清理
bmpMem.DeleteObject();
bmpMem2.DeleteObject();
dcMem.DeleteDC();
dcMem2.DeleteDC();
}
咋一看,好像没什么问题。
这程序在Timer中每100ms 运行一次this->Invalidate(0),我测试的WINCE 6中运行一直内存稳定,但是到了1个小时左右内存会迅速以4KB的速度一直减少
一直想不明白,最后发现原来是LoadBitmap惹的祸。
原程序中为了方便,将Attach和LoadBitmap写在了一条语句,但是LoadBitmap会返回一个HBITMAP的GDI句柄,MSDN中说到:
The application must call the DeleteObject function to delete each bitmap handle returned by the LoadBitmap function.
就是因为写在了一条语句上,所以忽略了它的返回值,导致有句柄没有删除引起内存泄漏。
原因知道了,下面改写代码:
void CWinXXXDlg::OnPaint()
{
CDC dcMem;
CBitmap bmpMem;
BITMAP bm2;
CBitmap *pOldBm2=NULL;
dcMem.CreateCompatibleDC(&dc);
bmpMem.CreateCompatibleBitmap(&dc,800,480);
CBitmap *pOldBm=dcMem.SelectObject(&bmpMem);
CDC dcMem2;
dcMem2.CreateCompatibleDC(&dcMem);
CBitmap bmpMem2;
HBITMAP hbitmap=::LoadBitmap( AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP_BACKGROUND));//改成返回hbitmap
bmpMem2.Attach(hbitmap); //通过句柄进行Attach背景
bmpMem2.GetBitmap(&bm2);
pOldBm2=dcMem2.SelectObject(&bmpMem2);//选BITMAP
dcMem.BitBlt(0,0,800,480,&dcMem2,0,0,SRCCOPY); //画背景位图
dcMem2.SelectObject(pOldBm2);//选回旧的bitmap进行清理内存
DeleteObject(hbitmap);//最后还要使用这个删除HBITMAP句柄
bmpMem2.Detach();
dcMem.SelectObject(pOldBm);//选回旧的bitmap进行清理
bmpMem.DeleteObject();
bmpMem2.DeleteObject();
dcMem.DeleteDC();
dcMem2.DeleteDC();
}
相关文章推荐
- static关键字所导致的内存泄漏问题
- static关键字所导致的内存泄漏问题
- 微信小程序用户信息解密失败导致的内存泄漏问题。
- 删除内存树结构的时候,千万注意内存泄漏问题,采用递归比较简单。
- static关键字所导致的内存泄漏问题
- tableView滑动删除,返回导致程序崩溃问题
- 不显示删除回复显示所有回复显示星级回复显示得分回复 [推荐] [百度分享]频繁分配释放内存导致的性能问题的分析
- MFC中onctlcolor函数返回的画刷导致的内存资源泄露问题
- android中共享全局数据的方法(static导致的内存泄漏问题,但其实并未解决)
- static关键字所导致的内存泄漏问题
- Spark性能优化-------troubleshooting之解决算子函数返回NULL导致的问题
- jquery使用不当导致内存泄漏
- Android开发编码规范导致的内存泄露问题
- 因WKWebview导致视图控制器释放不掉而内存崩溃的问题
- [置顶] ORACLE一次大量数据删除导致问题的处理
- 开发问题火狐出现内存泄漏错误
- 关于Python multiprocessing.Array创建的共享内存无法删除的问题
- 频繁分配释放内存导致的性能问题的分析
- PHP+FPM导致内存耗光的问题
- Android - 通过真实案例学习解内存泄漏问题,最终发现Android原生Bug