Jump to content

An introductory guide to Windows Memory Management


Recommended Posts

Everybody's familiar with "virtual memory", right? You've got a page file on some disk somewhere, and you've got RAM in your case. You know how to open up Task Manager, look at the Mem Usage column to see how much RAM stuff is using. You know how to look at the PF Usage graph in Task Manager to see how much memory you're using. You think you know it all.

:doh: You're wrong.

I'm going to give a brief overview of the concepts of Windows memory management, and perhaps enlighten you a little in the process. Next time you want to burst into a thread and say that Foosoft Transmogrifier sucks because it's using 40,000K in the Mem Usage column, maybe you'll think back to this and reconsider.

Let's start right off with the most often seen, and most misunderstood value available for you to feast your hungry little peepers on: the PF Usage graph. This is not total memory usage at all. It's measuring virtual memory, and only a portion of it. It's the sum of all processes' "VM Size" column from the Processes tab, and some system stuff that you can directly measure (like the paged pool), and some stuff you can't. The misleading "VM Size" column for a process is what's called "private bytes" by the Performance control panel. It's memory that's private to that process; generally it's the amount of RAM the process has asked for in order to store runtime data. It, in general, doesn't include any DLLs loaded by the process unless they've been rebased (though it may include memory allocated by those DLLs).

Commit Charge is the combination of both the actual pagefile usage, and any memory used in every's process's VM to store things actually written to memory. If for some reason, everything needed to be dumped out of physical RAM, that's how big your pagefile would need to be to store it all. Some of it's in RAM, some is in the pagefile. If you want to know how much of it is actually IN the pagefile on disk, find out the size of your pagefile, then multiply it by the "% Usage" counter in the Performance control panel's Page File object. Don't attach sentimental value to the on-disk usage because it's fluid, based on actual usage needs. Stuff can get put out on disk even if you're not out of RAM.

But, the Commit Charge is not all memory currently being used. It's only the memory that the pagefile needs to back up. There is lots of stuff that doesn't need to be written to the page file; primarily code loaded out of EXEs and DLLs, and memory-mapped files. Those already exist on disk, so there's no need for them to be pagefile backed.

If you want to get an idea of how much memory you're using like this, use the Performance control panel to retrieve the "Virtual Bytes", "Working Set", and "Private Bytes" for a process. "Private Bytes" is the same thing the Task Manager misleadingly refers to as "VM Size". "Working Set" is what the Task Manager calls "Mem Usage", which is the portion of the processes' address space ("Private Bytes" plus memory mapped files) that is currently resident in RAM and can be referenced without a page fault). "Virtual Bytes" is the total virtual address space of the process, which includes both private bytes and memory-mapped stuff.

If you add up all of the processes' "Virtual Bytes", you'll likely find it adds up to way more memory than you actually have. That's because those memory-mapped files, EXEs, DLLs, etc. can be shared among processes; and the same physical page in RAM can be accessed in more than one's process's address space at once (they're mounted read-only, or maybe copy-on-write, don't worry about cross-process corruption).

Since the Working Set is comprised both of Private Bytes and mapped files -- so you can't just add up all of the process's Working Sets (Mem Usage) to find out how much RAM you're using.

What the Performance control panel's System object calls "Cache Bytes" is the system's Working Set. This is where the paged pool and the disk cache resides. It's a normal Working Set, just like any normal process's, so it can be booted out of memory whenever RAM is needed for something else. (It's not part of the Commit Charge because it's a cache -- losing the data in here doesn't matter.) Because it competes alongside with the other processes for your physical RAM, that means any process that's open but not actively using some parts memory will have its Working Set automatically shrunk as the system, or another process, needs the RAM. If you want the part of the system Working Set that comprises the disk cache, that's called "System Cache Resident Bytes" in the Performance control panel. The paged pool is called "Paged Pool Resident Bytes". There are a couple other parts of the system's working set, system and driver code resident bytes, but they're usually negligable.

(The system also has nonpaged memory that always resides in RAM and can't be taken over under load -- the core system itself, the nonpaged pool, and driver code.)

Now, these Cache Bytes are different than what the Task Manager calls the System Cache. Task Manager's System Cache is actually Cache Bytes plus the standby page list. To make matters more confusing, the standby page list is also included in the "Available" physical memory reading in the Task Manager -- because it technically is available, but at the same time it technically is a cache.

The standby page list is how the OS gives memory to processes, and at the same time delays writing something out to the pagefile on disk until its absolutely necessary. When a page of memory is dropped from a process's working set, it doesn't just disappear into an opaque "free memory" block, it gets put on the tail end of a list, the standby page list. When a process needs new memory in its working set, the standby page list is the last place the OS looks. First, it looks in the zero page list, or the free page list, both of which are "free memory". One list is initialized to zeroes, one's not -- and they're hit up depending on what the process said it wanted. Only when both of those are empty does the system look to the standby page list.

The standby page list is raided last because, in the meantime, if a process has released a page from its working set, then later asks for it back (via a page fault, which is when a process asks for some of its memory that isn't currently in its working set), the system can check the standby page list to see if it happens to still be around. If it is, the OS can just take it out and give it back to the process without having to hit the disk for it. A large majority of page faults are resolved from the standby page list without having to hit the disk to retrieve the page.

So think about these factors acting together next time you take a look at your Task Manager and your eyes bug out when you see a process reporting extremely high Mem Usage. It's a combination of two things: Yes, that process is using a lot of memory, but that's no big deal because not all of that memory is expensive to page, but also that no other process in the system currently needs any of that memory. You can see this "needs" effect in action if you take a Firefox window, look at its Mem Usage in Task Manager, then minimize it. The working set size will fall through the floor, because Firefox tells the OS that the user just minimized it, so it likely doesn't need to keep that all RAM for its own use -- everything non-shared is immediately released to the standby page list. You'll find that most Windows application exhibit the same behavior.

Some people turn this behavior of Firefox off because they don't like the disk thrashing they get when they restore the Firefox window. Generally this will only happen on a system with not enough RAM, because as I've described, unless you're using physical RAM to the brim, when you bring Firefox back up, all of that memory will likely still exist in the standby page list and will be restored to Firefox immediately without the disk hit. However, if you turn that option off, Firefox will try to maintain its working set when you minimize it, which will likely degrade the performance of your other applications (since as memory is needed, the OS is forced to yank it away from Firefox on demand, which requires that it be committed out to the pagefile for later recovery while the application that needs it is waiting.)

In pathological cases, this fighting over working set space between applications is called "thrashing".

So how can you tell if you need more memory? As I've explained, you can't just open up Task Manager and start adding up numbers to compare against how much RAM you have. From a practical standpoint, do you have to wait often while the disk is hit when switching around between applications? Does the disk constantly grind while applications running in the background fight over RAM? If yes, you need more memory. How much more do you need? Look at how much the working sets are changing -- you should add enough to cover the difference between every process's low and high points; you actually really only need a little less because of the shared pages weirding up the numbers, but RAM is cheap and you'll be much happier if you overestimate rather than underestimate. (TL;DR version: just throw another fucking 512M stick in there already.)

Source: shsc.info

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...