O Memory, Where Art Thou?
by Robert Blanchet Jr. · 09/22/2006 (4:31 pm) · 8 comments
I wanted to address some issues I've seen people bring up about memory, memory leaks, etc. This .plan isn't meant to discuss finding memory leaks. For that I'll point you to the Memory Manager TDN article. What I do want to talk about however, is how to tell if there is a memory leak in your program.
You may be thinking, well this seems quite obvious, open the Windows Task Manager and look at your executable's memory usage. If the memory goes up but never goes down then I'm leaking memory, right?

Wrong.
While the Windows Task Manager may give you an indication of the memory "requirements" of your application, it isn't giving you the entire story.
The Windows OS employs something like a memory cache for each actively running program. This cache may grow as the needs of a particular program require using magical algorithms Microsoft developers have produced for determining the optimal size for that program. For instance a program over the course of it's life time may require 20 megs of memory but occasionally needs to load data requiring allocations of up to 10 additional megs which is released seconds after it is loaded and processed. The Windows OS may determine then, that the memory cache for this program must increase from the base 20 megs to 25 megs instead. Looking at the Windows Task Manager then, you may see that this program is now using 25 megs of memory, even though currently, it may only be using 20 megs.
That is, the Windows Task Manager is reporting the memory cache allotment and not the memory allocated and used by the program. This is not the same as a memory leak. The program has little to no control over the memory cache allotment the OS has given it.
You'll find that Torque uses similar methods for enhancing performance, for instance the FrameAllocator. The FrameAllocator allocates a chunk of memory, which can then be divided out in smaller chunks to those who request it. When faced with making a bunch of small allocations the FrameAllocator can save us the overhead of making those allocations by just giving us small portions of an already allocated memory chunk.
To determine whether or not a process is experiencing memory leaks, use Windows Performance Monitor (Perfmon.exe) and monitor the Private Bytes under the Process category for your application. Note, that the Performance Monitor also suffers from the same problem the Task Manager does. It is showing us the cache allotment for our program. However it does so using a nifty graph that helps us keep track of the memory over time.

There are two key things to pay attention to when using the Performance Monitor. Private bytes is the total memory that the process has allocated, but is not sharing with other processes. Note that this is different from Virtual Bytes, which is also interesting to monitor. Virtual Bytes is the current size in bytes of the virtual address space that the process uses. An application can leak virtual memory, but may not see a difference in the private bytes that are allocated. If you do not see memory increase when you monitor private bytes, but you suspect that you are still running out of memory, monitor virtual bytes to see if you are using up virtual memory.

The Performance Monitor defaults to some wacky display settings for the graph and counter. You'll want to adjust those settings so you can better read the graph. For the counters for private and virtual bytes you'll want to change the scale to a setting of 1.0 and for the graph you'll want to change the vertical scale to 100,000,000 which gives you a graphing scale of 0mb to 100mb.

To make sure that your application is leaking memory, put the suspect code in a loop with many iterations, and then monitor private and virtual bytes for any increases of memory. Watch to make sure that the number of private bytes and virtual bytes does not eventually stay the same and the number stops increasing. If there is a point at which the memory stops increasing, (for example, it does not continue to climb indefinitely) you do not see a memory leak but more likely, you see a cache that is growing to its maximum size.
You may be thinking, well this seems quite obvious, open the Windows Task Manager and look at your executable's memory usage. If the memory goes up but never goes down then I'm leaking memory, right?
Wrong.
While the Windows Task Manager may give you an indication of the memory "requirements" of your application, it isn't giving you the entire story.
Quote:
From MSDN:
If you think that you are experiencing a memory leak, be aware that memory leaks may not be what they appear to be. You may discover that a memory leak is not a true memory leak, but is a performance enhancement.
The Windows OS employs something like a memory cache for each actively running program. This cache may grow as the needs of a particular program require using magical algorithms Microsoft developers have produced for determining the optimal size for that program. For instance a program over the course of it's life time may require 20 megs of memory but occasionally needs to load data requiring allocations of up to 10 additional megs which is released seconds after it is loaded and processed. The Windows OS may determine then, that the memory cache for this program must increase from the base 20 megs to 25 megs instead. Looking at the Windows Task Manager then, you may see that this program is now using 25 megs of memory, even though currently, it may only be using 20 megs.
That is, the Windows Task Manager is reporting the memory cache allotment and not the memory allocated and used by the program. This is not the same as a memory leak. The program has little to no control over the memory cache allotment the OS has given it.
You'll find that Torque uses similar methods for enhancing performance, for instance the FrameAllocator. The FrameAllocator allocates a chunk of memory, which can then be divided out in smaller chunks to those who request it. When faced with making a bunch of small allocations the FrameAllocator can save us the overhead of making those allocations by just giving us small portions of an already allocated memory chunk.
To determine whether or not a process is experiencing memory leaks, use Windows Performance Monitor (Perfmon.exe) and monitor the Private Bytes under the Process category for your application. Note, that the Performance Monitor also suffers from the same problem the Task Manager does. It is showing us the cache allotment for our program. However it does so using a nifty graph that helps us keep track of the memory over time.
There are two key things to pay attention to when using the Performance Monitor. Private bytes is the total memory that the process has allocated, but is not sharing with other processes. Note that this is different from Virtual Bytes, which is also interesting to monitor. Virtual Bytes is the current size in bytes of the virtual address space that the process uses. An application can leak virtual memory, but may not see a difference in the private bytes that are allocated. If you do not see memory increase when you monitor private bytes, but you suspect that you are still running out of memory, monitor virtual bytes to see if you are using up virtual memory.
The Performance Monitor defaults to some wacky display settings for the graph and counter. You'll want to adjust those settings so you can better read the graph. For the counters for private and virtual bytes you'll want to change the scale to a setting of 1.0 and for the graph you'll want to change the vertical scale to 100,000,000 which gives you a graphing scale of 0mb to 100mb.
To make sure that your application is leaking memory, put the suspect code in a loop with many iterations, and then monitor private and virtual bytes for any increases of memory. Watch to make sure that the number of private bytes and virtual bytes does not eventually stay the same and the number stops increasing. If there is a point at which the memory stops increasing, (for example, it does not continue to climb indefinitely) you do not see a memory leak but more likely, you see a cache that is growing to its maximum size.
About the author
#2
Thats the WORDS describing all the stuff with memory :) Thanks a lot, I'll now send a link to this .plan to all my friends who interested on this :) I was not able to tell them "how-it-works" :)
09/22/2006 (4:47 pm)
great post!Thats the WORDS describing all the stuff with memory :) Thanks a lot, I'll now send a link to this .plan to all my friends who interested on this :) I was not able to tell them "how-it-works" :)
#3
09/22/2006 (4:53 pm)
Thanks for the info.
#4
09/22/2006 (5:10 pm)
It almost sounds like Robert knows what he is talking about, scary. :)
#6
Admittedly it only works predominantly on linux platforms, but torque is a crossplatform beast, including linux :-)
Gary (-;
09/22/2006 (10:12 pm)
My favorite among all tools, ever, for memory leak detection [and other stuffs]: The Valgrind suiteAdmittedly it only works predominantly on linux platforms, but torque is a crossplatform beast, including linux :-)
Gary (-;
#7
09/23/2006 (6:57 am)
Cool .plan. Excellent info.
#8
09/24/2006 (12:22 pm)
At my day job, I am still trying to convince the QA staff that Task Manager is useful for keeping track of handle and thread leaks, but not memory. Worse part is, it is an enterprise level server application, and memory usage should go up over time as it handles more connections, so early on in the QA process, I had to explain the the memory usage would in fact go up as the server load was increased. :) 
Associate Tom Eastman (Eastbeast314)
Cool stuff!