Solved

GDI leak question.

Posted on 2009-05-08
10
454 Views
Last Modified: 2013-12-27
I have an windows mobile app and i'm trying to track down why my app 'freezes' from time to time.  It happens after many hours of use and I dont know why.  I am going over every piece of code and inspecting it to see if I can find the problem.

In the OnPaint() of one of my dialogs I have the following code:

      CBitmap bmp;
       BITMAP bi;
       CClientDC dc(this);
       CDC bmDC;
       bmp.LoadBitmap(IDB_MYBITMAP);
       bmDC.CreateCompatibleDC(&dc);
       CBitmap *pOldbmp = bmDC.SelectObject(&bmp);
       bmp.GetBitmap(&bi);
       dc.BitBlt(xPos, yPos, bi.bmWidth, bi.bmHeight, &bmDC, 0, 0, SRCCOPY);

I have found out that I should have the following two lines added in after the last line above:

       bmDC.SelectObject(pOldbmp);
       bmDC.DeleteDC();

I want to understand the effect of not having the above two lines.  For example, some users may not use the dialog that this code in in often and others may use it more.  So far I cannot reproduce the 'freezing' defect.

Is there a way I can debug the above code and see the effecs of any GDI leak over time.  What variables should I be looking at?  SHould I monitor 'private bytes' etc??
0
Comment
Question by:Wanting2LearnMan
  • 4
  • 3
  • 2
  • +1
10 Comments
 
LVL 39

Assisted Solution

by:Kyle Abrahams
Kyle Abrahams earned 50 total points
Comment Utility
The effect of the 2 lines is that you're loading the file into memory, and then keeping it locked.  By not calling those lines, you're essentially saying "I'm still using this section of memory."  If possible I would monitor total used memory.  

It's not so much a GDI leak as it is a memory leak.  (Google on memory leaks and you'll get some detailed info.)

You said that it freezes only after several hours of use . . . if the above were the case you can keep calling the above code and make it crash faster.  I'm not sure if MFC has it's own garbage collection, but I doubt it.



0
 
LVL 44

Assisted Solution

by:AndyAinscow
AndyAinscow earned 100 total points
Comment Utility
I think it is in reality a resource HANDLE leak.  The system has only a fixed number of HANDLES (eg. 8192 - this isn't the correct value, just for example).  So as you do not release the bitmap each time you call the routine the handles in use will increase 1, 2, 3... 8191 and then 8192 and then BOOM!  or rather FREEZE! and wierd drawing behaviour.

I once coded a small app to monitor the usage on Windows 3.11 but I have forgotton exactly what function I used :-(

(ps. Might have changed since then. )
0
 

Author Comment

by:Wanting2LearnMan
Comment Utility
>>So as you do not release the bitmap each time
Do I need to do:
bmp.DeleteObject(); as well or are the below two lines enough

bmDC.SelectObject(pOldbmp);
bmDC.DeleteDC();

Thanks
0
 
LVL 44

Assisted Solution

by:AndyAinscow
AndyAinscow earned 100 total points
Comment Utility
The DeleteDC is not necessary - done for you in the CDC destructior.
0
 
LVL 33

Assisted Solution

by:pgnatyuk
pgnatyuk earned 350 total points
Comment Utility
Better to delete the DC when the "old bitmap" is selected there.
Why you need to load the bitmap each time when drawing? This bitmap is small enough?
So you need to delete it also or hope that a destructor will do it for you.
CreateCompatibleDC is also a question, if your app should work fast and does not freeze. You can make it once and keep.
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 33

Assisted Solution

by:pgnatyuk
pgnatyuk earned 350 total points
Comment Utility
Few things to add:
1. The same code can be compiled for Win32, so you can use BoundChecker to detect the errors. Microsoft has tools to detect erros on the device, but... it is not very easy to use. I don't know how you only with debugging your code may detect the GDI/memory problems. Maybe you can detect the fact that you have a leak, but, probably, not the place. So have your code compiled for Win32 and use BoundChecker.
2. Can you say if your control is derived from CWnd, CDialog, etc.? You don't use CPaintDC and I don't understand who validates the invalidated regions on your window.
0
 

Author Comment

by:Wanting2LearnMan
Comment Utility
>>Why you need to load the bitmap each time when drawing? This bitmap is small enough?
It is a real small bitmap.  I could try only loading it once to see if it makes any difference.

>>So have your code compiled for Win32 and use BoundChecker.
OK I'll try that also.

>>Can you say if your control is derived from CWnd, CDialog, etc.?
It is derived from CDialog.


Thanks for all the help.

0
 
LVL 33

Assisted Solution

by:pgnatyuk
pgnatyuk earned 350 total points
Comment Utility
So I'm afraid you have to call CDialog:OnPaint too. Otherwise you will have bad problems with the screen validating. And you have to use CPaintDC instead of your CClientDC
0
 

Author Comment

by:Wanting2LearnMan
Comment Utility
>>Otherwise you will have bad problems with the screen validating
What do you mean by this?

Thanks
0
 
LVL 33

Accepted Solution

by:
pgnatyuk earned 350 total points
Comment Utility
From my understanding it has to be something like that:
void CMyDlg::OnPaint()
{
    CPaintDC dc(this);
    CDialog::OnPaint();
     dc.BitBlt(xPos, yPos, m_nWidth, m_nHeight, &m_memDC, 0, 0, SRCCOPY);
}

all other stuff (bitmap loading, size detection, creating the memory DC, etc.) should be in OnInitDialog(), and object destroying (delete memory DC, delete the bitmap) should be in OnDestroy().
for example:
BOOL CMyDlg::OnInitDialog()
{
  CDialog::OnInitDialog();
  m_Bmp.LoadBitmap(IDB_MYBITMAP);
 //other:
//Create DC, SelectObject in this DC, etc.
}
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
In this article we will discuss all things related to StageFright bug, the most vulnerable bug of android devices.
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now