In Windows CE 6, the limit was raised to 2GB, so you have much more breathing room (you are limited to 512MB of physical RAM, but still, what luxury).
So, what do you do if you're developing for pre-6 Windows CE and you run out of heap space for your application? Well, you can play some tricks with DLL load ordering, but that only gets you so far. One neat trick I rely on is what I like to call the 'LMA incantation'. It goes like this:
If you ask for at least 2MB, and you ask for it in a particular way, then CE will allocate that memory for you from the Large Memory Area. This is the area of memory above where the individual 32MB slots exist for normal processes. It's normally used for memory-mapped files (which is another way you can make use of the LMA if you need to).
Here's the incantation:
DWORD size = 2*1024*1024; // (or more)
void *p = VirtualAlloc(0, size, MEM_RESERVE, PAGE_NOACCESS);
p = VirtualAlloc(p, size, MEM_COMMIT, PAGE_READWRITE);
#define LMA_START_ADDRESS (0x42000000)
assert(ptr > LMA_START_ADDRESS)
Now if you do this in one line rather than two, that is do the commit without the reserve, then you will get memory from your process' 32MB slot rather than the LMA, and the assert will of course fail.
This one has saved my behind on more than one project. Enjoy!
- From the MSDN description of VirtualAlloc:
In Windows CE 5.01 and earlier versions, if you call VirtualAlloc with dwSize >= 2 MB, flAllocationType set to MEM_RESERVE, and flProtect set to PAGE_NOACCESS, it automatically reserves memory at the shared memory region. This preserves per-process virtual memory.... Since CE 6.0, irrespective of the value of dwSize, kernel will always try to allocate VM in user process space. Also, user applications cannot call VirtualAlloc with shared heap address range (0x70000000 - 0x7fffffff) since this is read only for user applications and read/write for kernel mode threads.
- A recent article from CE whiz Doug Boling on CE memory architecture.
Oh well. So CE6 looks like it will be very interesting. We got betas of it and the big news is they've ditched the 32/32 limit of past CEs (up to 32 processes each with a 32Mb 'slot' of virtual address space); in CE6 each process gets its own 2Gb of virtual address space and up to 32k processes can be running simultaneously. Addressing of physical RAM is still limited to 512Mb, but DLLs now go in a shared 512Mb region of virtual address space, instead of eating from the 32Mb ceiling on down like before. That should mean worrying about DLL crunch when developing applications for PPC/WM is a thing of the past, at least for a little while.
On the whole I was glad I went. Most of the sessions were enlightening to one degree or another, although there were a couple of nightmares. One session included the pearl of wisdom "the emulator is good for emulating things". Boy, I'm glad my manager was at that one instead of me.