With ps
or similar tools you will only get the amount of memory pages allocated by that process. This number is correct, but:
does not reflect the actual amount of memory used by the application, only the amount of memory reserved for it
can be misleading if pages are shared, for example by several threads or by using dynamically linked libraries
If you really want to know what amount of memory your application actually uses, you need to run it within a profiler. For example, Valgrind can give you insights about the amount of memory used, and, more importantly, about possible memory leaks in your program. The heap profiler tool of Valgrind is called 'massif':
Massif is a heap profiler. It performs detailed heap profiling by taking regular snapshots of a program's heap. It produces a graph showing heap usage over time, including information about which parts of the program are responsible for the most memory allocations. The graph is supplemented by a text or HTML file that includes more information for determining where the most memory is being allocated. Massif runs programs about 20x slower than normal.
As explained in the Valgrind documentation, you need to run the program through Valgrind:
valgrind --tool=massif <executable> <arguments>
Massif writes a dump of memory usage snapshots (e.g. massif.out.12345
). These provide, (1) a timeline of memory usage, (2) for each snapshot, a record of where in your program memory was allocated. A great graphical tool for analyzing these files is massif-visualizer. But I found ms_print
, a simple text-based tool shipped with Valgrind, to be of great help already.
To find memory leaks, use the (default) memcheck
tool of valgrind.
I know this is a bit old but I can explain why your new equation works: (1/INTERVAL) * (pid diff)
It's just a simplification of the basic percentage equation 100 * (pid diff) / (cpu diff)
, which looks like what you were trying to do in your first example.
The cpu time in /proc/stat (and the utime and stime in /proc/pid/stat) is reported in USER_HZ (or jiffies). This value is usually 1/100 of a second. This means that there will be 100 "tics" in each second for the CPU, which means your "CPU diff" will be INTERVAL*100
.
Substitute that in and you get:
100 * (pid diff) / (INTERVAL * 100)
Cancel out the 100's and you are left with:
(pid diff) / INTERVAL
Which is the same as what you are now using. This also means that if you did indeed correct the problems you have in the code at the top, then that should work as well. The pid diff should be (curr utime + curr stime) - (prev utime + prev stime)
. If it doesn't work, then perhaps the way you are adding up the CPU time is wrong? It'd be easy to test because you know what value it should be (INTERVAL*100)
.
Since you now have a working equation, you may not care to figure out the problem with the original code but keep in mind that if you ever try to use it on a system where USER_HZ is not 1/100, the equation will be invalid.
Best Answer
Preparation
To calculate CPU usage for a specific process you'll need the following:
/proc/uptime
#1
uptime of the system (seconds)/proc/[PID]/stat
#14
utime
- CPU time spent in user code, measured in clock ticks#15
stime
- CPU time spent in kernel code, measured in clock ticks#16
cutime
- Waited-for children's CPU time spent in user code (in clock ticks)#17
cstime
- Waited-for children's CPU time spent in kernel code (in clock ticks)#22
starttime
- Time when the process started, measured in clock ticksgetconf CLK_TCK
can be used to return the number of clock ticks.sysconf(_SC_CLK_TCK)
C function call may also be used to return the hertz value.Calculation
First we determine the total time spent for the process:
We also have to decide whether we want to include the time from children processes. If we do, then we add those values to
total_time
:Next we get the total elapsed time in seconds since the process started:
Finally we calculate the CPU usage percentage:
See also