GDI 对象的释放与内存泄漏的问题研究
最近写了一个GDI 绘图的程序,过程中遇到一个奇怪的问题,就是 定时器定时一会GDI绘的图就消失了。。后来经过分析,原来是 GDI对象数量过多 ,即GDI对象超过10000个 导致内存泄漏的问题。找到了问题所在,就好解决了,就是及时释放GDI对象。
在创建GDI对象的时候,遵循以下规则:
GetDC 得到的DC要用 ReleaseDC
CreateCompatibleDC 要用 DeleteDC
例如:
BOOL CLogicChartCtrl::DrawBmp( CDC* pDC, CRect rect, HBITMAP hBitmap ) { BITMAP bm; GetObject(hBitmap,sizeof(bm),(VOID*)&bm); INT nWidth = bm.bmWidth; INT nHeight = bm.bmHeight; CDC memdc; memdc.CreateCompatibleDC(pDC); CBitmap bitmap; bitmap.CreateCompatibleBitmap(pDC,nWidth,nHeight); memdc.SelectObject(hBitmap); BLENDFUNCTION bf = {AC_SRC_OVER,0,255,1}; pDC->AlphaBlend(rect.left,rect.top,nWidth,nHeight,&memdc,0,0,nWidth,nHeight,bf); m_bmp.Detach(); DeleteObject(hBitmap); DeleteObject(bitmap); DeleteDC(memdc); return TRUE; }
所以总结使用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选中使用.