Are there any known memory leaks with StretchBlt and BitBlt

I have a pretty straightforward bit of code that that uses two CDCs to paste an HBITMAP into a larger HBITMAP at a specified rect. The code works, but I was noticing a memory leak as the stitching was happening.  

When I first create the larger HBITMAP, I see the Virtual Memory usage in my task manager increase by the size of the bitmap, as I would expect. Correct me if I'm wrong, but when I then bit blit data into an area of that large HBITMAP, the "Mem Usage" column in the task manager should not necessarilly increase, correct?

When I commented out the StretchBlt line and let everything run, both the VM Size and Mem Usage values in the task manager remained the same. Allowing the StretchBlt to happen, and the Mem Usage column kept increasing, while VM Size stayed the same.

I use StretchBlt because my code is used both when I'm pasting a smaller image into a bigger image and when I"m pasting a bigger image into a smaller image, but in this case, I tried using BitBlt as well, and saw the same increase in Mem Usage.

Is there a problem with my code?   I don't understand why performing a StretchBlt (or BitBlt) would cause the memory used to increase.

thanks


-------------------------------------
CRect pasteRect;
GetRectAtIndex(a_iIndex, &pasteRect); // returns a 1000x1000 rect

CDC memDCImage, memDCThumbs;

memDCImage.CreateCompatibleDC(NULL);
memDCThumbs.CreateCompatibleDC(NULL);

BITMAP bmp;
::GetObject(a_hbmImage,sizeof(BITMAP),&bmp);

HBITMAP hbmOldImage = (HBITMAP)memDCImage.SelectObject(a_hbmImage);
HBITMAP hbmOldThumb      = (HBITMAP)memDCThumbs.SelectObject(m_hbmThumbnailSurface);      
      
memDCThumbs.SetStretchBltMode(HALFTONE);
memDCThumbs.StretchBlt(pasteRect.left, pasteRect.top, pasteRect.Width(), pasteRect.Height(), &memDCImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);

memDCThumbs.SelectObject(hbmOldThumb);
memDCImage.SelectObject(hbmOldImage);

DeleteObject(hbmOldImage);
DeleteObject(hbmOldThumb);

memDCImage.DeleteDC();
memDCThumbs.DeleteDC();
-------------------------------------
PMH4514Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

DanRollinsCommented:
What APIs are you using to create the HBITMAP.  It is perfectly possible that those steps just cause the system to allocate memory and that no physical memory would be accessed until such time as you "touch" the data.  

I'll bet that you can see a similar jump in physical memory usage if you even use SetPixel -- anything that actually changes a value in the allocated memory -- including directly accessing it via its lpBits or SetDIBits() ... It might also jump if you use GetDIBits() since I'd assume that would cause the memory are to be locksed and thus forcing a change from virtual to physical.

-- Dan
0
PMH4514Author Commented:
Dan -
I create them using CreateDIBSection

I understand what you're saying, but in some instances, when the HBITMAP is created, I may see an increase in used Virtual Memory by upwards or 400MB depending on the size of the large image into which my sub-images are stitchec. My System Ram usage may start off around, oh say 20MB, but as the map is built, the system comes to a hault as the Mem Usage goes approaches the amount of physical RAM on the system.   If ~500MB of virtual ram were allocated for an HBITMAP that required 500MB, I don't understand why filling that space up would cause such a dramatic increase in used physical ram.

And if that is normal operation, how do I alleviate the problem?
0
DanRollinsCommented:
As you "touch" various parts of the address space, the system will have to make "real" RAM available.  Since it the most recently used, it is high priority and the system will have to start swapping out parts of other programs to disk... At some point, just dropping down a menu will cause the system to have to read code and data from the disk...

Another thought: The amount of VM actualized to real memory may vary depending upon the location in the bitmap.  For instance, touching the lower right corner might be much more "expensive" than touching the upper left.  

It might also depend on the shape the the BMP.   For instance, one that is 16,000 pixels wide consumes 48K of RAM per scanline.  I imagine touching just the leftmost pixel of each line would cause the entire line to be actualized into RAM.  So a "tall and narrow" blit to a really wide Bitmap could be very expensive.

=-=-=-=-=-=-=-=-=-=-=-=-=
The first thing I'd try is to use the FileMapping technique in the CreateDIBSection call.  It seems to me that there is a good chance the system will be quicker to page out parts of the huge BMP allocation in that case (it's the very reason for that feature).  It might use "sparse matrix" techniques to avoid gobbling vast tracts of disk and RAM space.

The next try would be much harder... you would need to find a way of avoiding ever having to use the whole BMP at once... that means manually seeking into the right parts of the file to locate the right pixel data -- as in http:/MFC/Q_20312390.html -- and read and write it manually (i.e., using techniques other than Bitblit or StretchBlit).  Though, it should be possible to StrtchBlit to smaller, temporary bitmaps formatted correctly and then transfer the resulting data to disk.

-- Dan
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Cloud Class® Course: Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

AndyAinscowFreelance programmer / ConsultantCommented:
Minor point.
A memory leak is typically assigning a block of memory with new, but later not freeing it with delete.  In DEBUG mode the IDE will give warnings when the app is closed.
0
PMH4514Author Commented:
right Andy, I did hesitate to use the term memory leak here, because the IDE wasn't giving such warnings. Perhaps what I'm seeing is in fact normal functionality as Dan is implying.
0
DanRollinsCommented:
It's a longshot, but it might be worth testing to see if the HALFTONE adjustment logic for your device driver is causing the extra memory to be allocated "behind the scenes".  Just comment out the line...
   memDCThumbs.SetStretchBltMode(HALFTONE);
ans see if the behavior changes.
0
PMH4514Author Commented:
yah no effect. I had tried various blt modes, including no specification, still see the same thing.

'course this may become moot with the code from my other question you've been helping with
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.