OutOfMemoryException when creating a large bitmap in CF.NET

The my compact framework application creates a list with a smooth scrolling, displaying all elements on a large raster surface, and then copying this raster image to the offset position on the screen so that only the corresponding elements are displayed. Older versions only displayed elements that should be displayed on the screen at that time, but this approach was too slow for a smooth scroll interface.

Sometimes it throws an OutOfMemoryException on the initial creation of a large bitmap. If the user performs a soft-reset of the device and starts the application again, he can perform the creation without any problems.

It does not look like this bitmap is being generated in program memory, since the application uses approximately the same amount of program memory as before new smooth scrolling methods.

Is there any way to prevent this exception? Is there a way to free the memory I need (wherever it is) before an exception is thrown?

+4
source share
4 answers

I would suggest reverting to the old mechanism of rendering only a part of the data, since the size of the fully rendered data is obviously a problem. To prevent rendering problems, I would probably pre-make a few lines above and below the current view so that they can be “scrolled” with limited impact.

+1
source

And as soon as I sent the message, I thought of something that you can do to fix your problem with the new version. You have a problem with CF that is trying to find one block of continuous memory available for a huge bitmap, and this is sometimes a problem.

Instead of creating one large bitmap, you can instead create a collection of smaller bitmaps, one for each item, and render each item in its own small bitmap. During the display, you simply copy the bitmap images that you need. It will be much easier for CF to create a bunch of small bitmaps than one large one, and you should not have memory problems if it is a really huge set of elements.

I should avoid expressions like "no fix."

Another important point: make sure you call Dispose () for each bitmap when you're done with it.

+1
source

Your bitmap is definitely created in the program memory. How much memory a bitmap requires depends on how large it is, and whether this required size will raise an OutOfMemoryException depends on how much PDA is available (which makes this a random mistake).

Sorry, but this is usually an inappropriate control visualization method (especially on the Compact Framework), for which there is no fix that does not increase the physical memory on the PDA, which is usually impossible (and often does not fix the problem in any case, since the CF process is limited to 32 MB no matter how accessible the device is).

It’s best to go back to the old version and improve its rendering speed. There is also a simple technique available for CF to control a double buffer to eliminate flicker.

0
source

Since it looks like you are faced with a device restriction that limits the total size of the Bitmap space that you can create (they are apparently created in video memory and not in shared program memory), one alternative is to replace a large object Bitmap used here with an open block of Windows memory, access to it for reading and writing using the PInvoking BitBlt API function.

Initially, creating a memory block is difficult, and you probably want to ask another question about what (GCHandle.Alloc can be used here to create a “pinned” object, which means that .NET cannot move this in memory, which is important here) . I know how to do this, but I'm not sure that I am doing it right, and I would prefer to get expert input.

After you have created a large block, you will iterate over your elements, display each in one small raster image, which you continue to reuse (using existing .NET code), and BitBlt in the appropriate place in your memory block.

After creating the entire cache, your rendering code should work the same way as before, with the difference that instead of copying from a large bitmap image to the BitBlt rendering surface from the cache block. The arguments for BitBlt are essentially the same as for DrawImage (destination, source, coordinates and sizes, etc.).

Since you are creating a cache from normal memory in this way instead of specialized video memory, I do not think that you will encounter the same problem. However, I would definitely get the block creation code working first, and check that it can create a sufficiently large block each time.

Update: in fact, the ideal approach would be to collect smaller blocks of memory, and not just one big one (as I thought it was a problem with the Bitmap approach), but that’s enough for you. I worked with CF applications that deal with objects of 5 and 10 MB, and this is not a huge problem anyway (although it can be a big problem when this piece is fixed - I do not know). BTW, OOME always surprised me in creating BitMap because I knew that bitmaps were much less memory available, like you - now I know why. Sorry, I thought it was easy to solve at first.

0
source

All Articles