|
||||
Very goog info on Paging and the Windows CE Paging Pool
I found this today and found it very informitve and thought i would share.
Paging and the Windows CE Paging Pool I’d like to explain a little more about memory management in Windows CE. I already explained a bit about paging in Windows CE when I discussed virtual memory. In short, the OS will delay committing memory as long as possible by only allocating pages on first access (known as demand paging). And when memory is running low, the OS will page data out of memory if it corresponds to a file – a DLL or EXE, or a file-backed memory-mapped file – because the OS can always page the data from the file back into memory later. (Win32 allows you to create “memory-mapped files” which do or do not correspond to files on disk – I call these file-backed and RAM-backed memory-mapped files, respectively.) Windows CE does not use a page file, which means that non file-backed data such as heap and thread stacks is never paged out to disk. So for the discussion of paging in this blog post I’m really talking only about memory that is used by executables and by file-backed memory-mapped files. It’s relatively easy to guess how the OS decides when to page data in to memory – it doesn’t page it in until it absolutely has to, when you actually access it. But how does the OS decide when to remove pageable data from memory? Ahh, that’s the question! The Paging Pool and How It Works Back in the old days of CE 3.0 or so (I’m not sure) – Windows CE did not have a paging pool. What that means is that the OS had no limit on the number of pages it could use for holding executables and memory-mapped files. If you ran a lot of programs or accessed large memory-mapped files, you’d see memory usage climb correspondingly. Usage would continue to go up until the system ran out of memory. Other allocations could fail; memory would appear to be nearly gone when really there was actually a lot of potential to free up space by paging data out again. Until finally when the system hit a low memory limit, the kernel would walk through all of the pageable data, paging everything (yes, everything) out again. Then suddenly there would be a lot of free memory, and you’d take page faults to page in any data you’re still actually using. The algorithm is simple, but it has a few bad effects. First, a bad effect of the simple paging algorithm was, obviously, that the system could encounter preventable RAM shortages. Also, it was really tough for applications or tools to measure free memory – where “free” includes currently-unused pages plus “temporary” pages that could be decommitted when necessary. Conversely, it was difficult for users to determine how much of an application’s memory usage is fixed in RAM vs. “temporary” pageable pages. Even today it is tough to answer the question “how much memory is my process using?” in simple terms without diving into explanations of paging, cross-process shared memory, etc. Another possible problem you can encounter when there’s no paging pool is that the rest of the system can take up all of the free memory, and leave you thrashing over just a few pages. So we introduced the paging pool. The purpose of the paging pool is to serve as a limit on the amount of memory that could be consumed by pageable data. It also includes the algorithm for choosing the order in which to remove pageable data from memory. Pool behavior is under the OEM’s control – Microsoft sets default parameters for the paging pool, but OEMs have the ability to change those settings. Applications do not have the ability to set the behavior for their own executables or memory-mapped files. Up to and including CE 5.x, the paging pool behavior was fairly simple. ·The pool only managed read-only pageable data. Executable code is read-only so it used the pool, and so did read-only file-backed memory-mapped files. Read-write memory-mapped files did not use the pool, however. The reason is that paging out read-write data can involve writing back to a file. This is more complicated to implement and requires more care to avoid file system deadlocks and other undesirable situations. So read-write memory-mapped files had no memory usage limitations and could still consume all of the available system RAM. ·The pool had one parameter, the size. OEMs could turn the pool off by setting the size to 0. Turning off the paging pool meant that the OS did not limit pageable data – behavior would follow the pattern described above from before we had a paging pool. Turning on the pool meant that the OS would reserve a fixed amount of RAM for paging. Setting the pool size too low meant that pages could be paged out too early, while they’re still in use. Setting the pool size too high meant that the OS would reserve too much RAM for paging. Pool memory would NOT be available for applications to use if the pool was underutilized. A 4MB pool took 4MB of physical RAM, no matter whether there was only 2MB of pageable data in use or 100MB. Setting the size of the pool was a tricky job, because you had to decide whether to optimize a typical steady-state situation with several applications running (and judge how much pool those applications would need), or optimize “spike” situations such as system boot where many more pages were needed for a short period of time. ·The kernel kept a round-robin FIFO ring of pool pages: the oldest page in memory – the earliest one to be paged in – was the first one paged out when something else needed to be paged in, regardless of whether the oldest page was still in use or not. So the short roll-up of how the paging pool worked up through CE 5.x is that the paging pool allowed OEMs to set aside a fixed amount of memory to hold read-only pageable data, and it was freed in simple round-robin fashion. In CE 6.0, the virtual memory architecture changes involved major rewriting of the Windows CE memory system, including the paging pool. The CE 6.0 paging pool behavior is still fairly simplistic, but is a little bit more flexible. ·CE 6.0 has two paging pools – the “loader” pool for executable code, and the “file” pool which is used by all file-backed memory-mapped files as well as the new CE 6.0 file cache filter, or “cache manager.” This way, OEMs can put limitations on memory usage for read-write data in addition to read-only data. And they can set separate limitations for memory usage by code vs. data. ·The two pools have several parameters. Primary of these are target and maximum sizes. The idea is that the OS always guarantees the pool will have at least its target amount of memory to use. If memory is available, the kernel allows the pool to consume memory above its target. But when that happens, it also wakes up a low-priority thread which starts paging data out again, back down to slightly below the target. That way, during busy “spikes” of memory usage, such as during system boot, the system can consume more memory for pageable data. But in the steady-state, the system will hover near its target pool memory usage. The maximum size puts a hard limit on the memory consumption – or OEMs could set the maximum to be very large to avoid placing a limit on the pool. OEMs can also get the old pre-CE6 behavior by setting the pool target and maximum to the same size. ·Due to the details of the new CE6 memory implementation, the FIFO ring of pages by age was not possible. The CE6 kernel pages out memory by walking the lists of modules and files, paging out one module/file at a time. This is no better than the FIFO ring, but still leaves us potential for implementing better use-based algorithms in the future. Source http://blogs.gotdotnet.com/ce_base/archive/2008/01/19/Paging-and-the-Windows-CE-Paging-Pool.aspx |
|
||||
Re: Very goog info on Paging and the Windows CE Paging Pool
There are some more details in our documentation under “Paging Pool” and “Paging Pool: Windows CE 5.0 vs. Windows Embedded CE 6.0.”
Overall, enabling the paging pool means that there is always some RAM reserved for code paging and we will be less likely to reach low-memory conditions. In general it's better to turn on the paging pool because it gives you more predictable performance, rather than occasional long delays you’d hit when cleaning up memory when you run out. But it does need to be sized based on the applications in use, which leads to my next point... Choosing a Pool Size In Windows CE (embedded) 5.0, the pool is turned off by default. In Windows Mobile, the pool is turned on and set to a default size chosen by Microsoft. I believe it varies between versions, but is somewhere in the neighborhood of 4-6 MB. In CE6, the loader pool has a target size of 3MB and the file pool has a target size of 1MB. Only the OEM of a device can set the pool size; applications cannot change it. |
|
|
|