Do not use Task Manager for Memory Info

As a windows user for many many years, Task Manager is a friend. Through the years, I have used it to kill hundreds of misbehaving apps and getting info about which ones are exhausting my resources. Until I started working with machines that have 100s of GBs of memory and apps with memory consumption to match. In this post, I would like to discuss how it can be lacking as a memory tracker, and go over alternatives that could replace it. First, let’s discuss how memory allocations work in Windows.

tl;dr: Task Manager hides info about Process Paged Memory and its Virtual Space. Use Process Explorer instead.

Allocations in Windows

Whenever a new process starts, OS assigns a continuous address space to that the process. In 32-bit systems, this space is 4GB, with usually 2GB for kernel use, and the rest for the process. For this post, let’s ignore kernel usage. For 64-bit systems reserved process memory can grow to a whopping 64TB. What’s the process is going to do with several TBs when we actually have a measly 8GB RAM? We’d need first to understand reserving vs committing memory.

Reserving vs Committing memory

Not all parts of that huge address space are equal. Some parts of Process Address Space is actually backed by either physical RAM, or by the disk (explained below). Memory that is backed is referred to as Committed, as in, the OS is committed to offering you that memory if you try to use it. The rest of the Address Space, and that’s the vast majority, is Reservable' memory. That is, it is not certain OS can offer you this block of memory to use: it might be able to back it up with disk (Page File`) for example, but it might not. In C++, reserving a piece of memory can be achieved through a call to VirtualAlloc. Committed memory is then the actual resource limit in the OS since it’s backed by hardware. Let’s give it a look.

OS Paging

OS Paging is an amazing idea. Basically, the OS realizes some parts of the memory are not used a lot by your app. Now, why waste previous physical memory on that? A process in the kernel writes this unused chunk to the disk instead. Until it gets accessed again, only then it gets brought back into memory.

For a more detailed explanation of how memory works in windows, I cannot recommend enough Mark Russinovich’s Mysteries of Memory Management Revealed.

Memory Tracking

Now that’s a lot of info to track – with many scenarios to apply. Whom to turn to? Of course, it’s Task Manager!

Memory that is backed by RAM is generally referred to as Working Set, while Private Bytes, in general, are the overall committed memory. Dlls make definitions a little more complicated, so let’s ignore them for now. In other words:

Private Bytes [Committed Memory] =  Working Set + Page File 

By default, Task Manager shows Working Set under any process:

Default Task Manager

And that’s the number I used to look at all the time. Little did I know, Task Manager actually has the commit info, but it’s under the column Commit Size. I so far could not find Virtual Memory info in there.

Task Manager after adding Commit Size Task Manager allows adding Commit Size by right-clicking columns and adding it

Effective Memory Metrics

Thankfully, there are many other resources to examine Perf in Windows. Every windows machine has PerfMon that can be used to expose very detailed info about each process and the system in general:

PerfMon

Interestingly, PerfMon can actually examine & compare metrics across two or more machines in the network. It’s very powerful, but Task Manager is obviously more user-friendly. In order to get an in-the-middle solution, I recommend Process Explorer:

Process ExplorerProcess Explorer System Info

Boom! Visual Studio, why are yous till 32-bit (notice its Virtual Size)? My computer’s peak memory usage has been at 89% of its limit, not too shabby. This comes in useful later.

Edit: many has pointed out other tools that might come in handy too, specifically VMMap and RAMMap.

Debugging with Memory Info

Fortunately, this info is not just some OS trivia. It has time and time helped me debug various issues.

Most importantly, is figuring out the untouched parts of committed memory. The paged part of the process represents a very important piece of information: memory committed and not used frequently or rarely used.

Even if this memory is going to be used occasionally, it is important to realize that this access is going to be expensive, and doing this on the hot path is a no-no. Leaked memory should show up as part of this value too.

For these reasons, I have previously heard it suggested to remove PageFiles completely, effectively making Private Bytes == Working Set. However, it’s a double-edged idea though. This renders the OS unable to discard memory for misbehaving apps, which could sometimes include OS apps allocating data not needed in memory.


Thanks for reading! Follow my updates on @aybassiouny

7
Leave a Reply

avatar
3 Comment threads
4 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
4 Comment authors
WizardLuis de SantiagoaybassiounyBryan Recent comment authors
  Subscribe  
newest oldest most voted
Notify of
Bryan
Guest
Bryan

Should that equation be:

Private Bytes [Committed Memory] = Working Set + Page File

Luis de Santiago
Guest
Luis de Santiago

Hey Ahmed
Excellent article. Only one thing. Regarding the question “Boom! Visual Studio, why are yous till 32-bit”. I have read the answer in Rico Mariani’s blog. Haven’t found the original post that I read, but this is good enough: https://www.infoq.com/news/2016/01/VS-64-bit

Wizard
Guest
Wizard

Great article! I wish you could go deeper into this program, and btw your anchors at the beginning of the article don’t work