Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

GDI leak question.

Posted on 2009-05-08
10
Medium Priority
?
525 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
  • 2
  • +1
10 Comments
 
LVL 41

Assisted Solution

by:Kyle Abrahams
Kyle Abrahams earned 200 total points
ID: 24335446
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 45

Assisted Solution

by:AndyAinscow
AndyAinscow earned 400 total points
ID: 24342657
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
ID: 24343031
>>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
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 45

Assisted Solution

by:AndyAinscow
AndyAinscow earned 400 total points
ID: 24344356
The DeleteDC is not necessary - done for you in the CDC destructior.
0
 
LVL 33

Assisted Solution

by:pgnatyuk
pgnatyuk earned 1400 total points
ID: 24346865
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
 
LVL 33

Assisted Solution

by:pgnatyuk
pgnatyuk earned 1400 total points
ID: 24347172
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
ID: 24352402
>>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 1400 total points
ID: 24352498
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
ID: 24352573
>>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 1400 total points
ID: 24353290
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

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
Article by: evilrix
Looking for a way to avoid searching through large data sets for data that doesn't exist? A Bloom Filter might be what you need. This data structure is a probabilistic filter that allows you to avoid unnecessary searches when you know the data defin…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
Suggested Courses

610 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