Wednesday, November 19, 2008

The quest for a smooth-scrolling interface - Ouch

In my last post, I discussed my great new idea for smooth scrolling in PockeTwit. I tested it for a good while on my Sprint Mogul and several emulators. I even had several users try out the dev build before release. I felt satisfied it was ok, so I put it in the wild.

And immediately my email began filling up with crash reports. I got to work and was able to solve all the issues pretty quickly except one -- an "OutOfMemoryException" that was coming up almost immediately on startup for many users.

This one was a bit of a mystery. I figured out that most of the users with the error were using newer devices with VGA screens. Typically, these devices have WAY more memory than the old ones without a problem. To make it even more strange, the device claimed to have plenty of free Program Memory.

The problem was obviously with my new method of generating a new huge bitmap surface to render all the statuses on. Even if the device had plenty of free memory, it would often fail creating that bitmap. It would usually run without issue after a soft reset. When I looked at a task manager, the program looked like it was using the same amount of memory as before!

A more careful look showed that not everything was the same. I was creating a big giant bitmap and I knew that had to take up more memory somewhere. My process (PockeTwit.exe) was using the same amount of memory, but another process had quadrupled in size!

After some more research I discovered that all bitmaps in memory are assigned to their a seperate process -- gwes.exe (Graphics, Windowing, and Events Subsystem). It handles all device-specific graphics functions, and my bitmaps fell under it's umbrella.

But it still didn't explain the OutOfMemory error. The device itself still had plenty of memory. I had to dig even more to discover that each process in Windows CE 5 (which is what Windows Mobile is based on) can use up no more than 32M of memory. On VGA devices, combining my giant bitmap with the bitmaps of all the other applications on the device would sometimes put gwes.exe over that limit. I finally found the cause of my solution.

So, to sum up the problem:
  1. I make a giant bitmap.
  2. Because of the architecture of the OS, that bitmap is assigned to gwes.exe instead of my process.
  3. gwes.exe may expand past the 32M of memory per process limit.
Now that I understand the cause of the problem, it's time to work on a solution that will let me keep my smooth scrolling without using up so much bitmap memory.


Chu said...

You might want to check out the memory "hacks" described here and its follow-up here

Jake Stevenson said...

Wow, that's some very interesting reading. While it doesn't fix my original problem, it certainly will help.