As a diligent IT professional, you decide you want to run perfmon to monitor the memory usage on a few of your servers. Not being 100% familiar with what all the counters mean, you do a bit of research and decide that one of the counters you want to look at is Committed Bytes. Good choice, this is an important counter which shows you how much memory Windows has committed to make available to processes if and when they need it. Wanting to know what perfmon has to say about this counter, you open it up and see the following description:
Committed Bytes is the amount of committed virtual memory, in bytes. Committed memory is the physical memory which has space reserved on the disk paging file(s)
Unfortunately, this description (and the description for Commit Limit and % Committed Bytes In Use) is wrong. Interestingly, if you go all the way back to Windows 2003 (and possibly further than that) and skip forward to Windows 10, the same incorrect description is there all the way through. This is a good example of how difficult it is to truly understand the counters relating to memory management. Let’s take a look at what is wrong with this description.
Spare Me The Details!
If you don’t care too much about the details, the easy way of showing that the description is wrong is to remove your page file and see if Committed Bytes is zero. After all, the implication in the description is that committed memory has space reserved in the page file. Therefore, without a page file you can’t reserve said space in the page file and therefore can’t have any Committed Bytes. If you turn off your page file, you’ll see that you will still have a non-zero value for Committed Bytes just like you did with the page file still present. Case closed!
Give Me The Details!
Ok, you asked for it – things are going to get technical now. Let’s first look at what memory commitment is. When a process starts up, it needs memory. However, it doesn’t know exactly how much memory it’s going to need ahead of time. It might need 100 MB or it might need 500 MB depending on load. Let’s say that Windows has 800 MB of free memory when the process first starts up. No problems here – even under full load the 500 MB requirement of our fictitious process can be met. But what if it only needs the full 500 MB four days after starting up? By that time, there may only be 100 MB of available memory in Windows at which point our process is going to be very unhappy when it asks for the full 500 MB and the allocation fails. Avoiding this situation is what memory commitment is all about. It allows a process to reserve a given amount of memory and Windows will promise to make the memory available should the process need it, even if this request comes weeks after the process first started. They key, of course, is for Windows to ensure that it doesn’t agree to provide more memory to processes than it can physically provide. We’ll look at how it does this in the next paragraph when we talk about the Commit Limit.
Needless to say, you’ve probably realized by this point that the concept of “reservation” from the built-in perfmon description is accurate. What’s not accurate is where the reservation is held. To see why this is the case, we first need to understand where this committed memory is being drawn from. Windows has a value known as the Commit Limit. This is the maximum amount of memory that Windows can promise to make available to processes and is composed (approximately) of the amount of physical RAM plus the size of the paging file(s). For example, if you have 4 GB of RAM and a 2 GB Page File, you have a 6 GB Commit Limit. Related to the Commit Limit, we have the Commit Charge. The Commit Charge is how much memory Windows has promised to make available to processes if and when they need it and is what is represented by the Committed Bytes counter we’re discussing in this post.
And now we get to the crux of the matter. When Windows says, “I solemnly promise to reserve 500 MB of memory for you” (making the Committed Bytes counter go up by by 500 MB as well) it’s not reserving that space in the page file, contrary to what the description says. What it is instead doing is setting aside 500 MB of memory for the process and then adding 500 MB to the Commit Charge. If and when the process actually uses that memory, the page file may come into play or it may not, depending on what the Windows memory manager decides is best at that point in time. If a request for memory from a process will make the Commit Charge exceed the Commit Limit, the request will fail (or the page file will need to be expanded).
So in summary – the built-in description for Committed Bytes states that committed memory is memory which has space reserved in the page file. In this post we have seen that committed memory is a memory reservation, represented by Committed Bytes, which is charged against the Commit Limit and that there is no specific tie-in to where that memory reservation is being held.