windows ce
Breaking the 32MB barrier on Windows (pre-6) CE
Wednesday, 26 September 2007
In Windows CE 5 and earlier, each process is limited to 32MB of virtual address space. That 32MB has to hold your executable, your DLLs, everyone else's DLLs, your heap, and some other stuff. If you're on a plain Windows CE device the so-called 'DLL crunch' isn't always too bad, since the OEM only has to include what they want or need to include in the platform image. However, on a Windows Mobile device, the OEM has to include everything required to get LTK verification: Pocket Word, and all that fun stuff. That means a bunch of extra DLLs that eat into the available space in your process' slot.
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:
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!
Notes:
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);
// optional:
#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!
Notes:
- 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.
MEDC 2006
Saturday, 13 May 2006
I just got back from Microsoft's Mobile and Embedded DevCon. It was hosted at The Venetian in Las Vegas. On Tuesday night they had Tao, this nightclub in the hotel, reserved exclusively for MEDC; it must have been the largest nerd conglomeration in a nightclub ever! We entered the SumoRobot challenge, where we had to program the AI in a Parallax SumoRobot modified to use the new .NET Micro Framework. I lost one of the IR sensors on the way into the ring and the poor robot was never the same after that.
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.
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.