I have shown how to measure the size of the process’ shared memory,
but we still want to know what the real memory usage is. Obviously
this cannot be calculated simply by adding up the memory size of each
process because that wouldn’t account for the shared memory.
On the other hand we cannot just subtract the shared memory size from
the total size to get the real memory usage numbers, because in
reality each process has a different history of processed requests,
therefore the shared memory is not the same for all processes.
So how do we measure the real memory size used by the server we run?
It’s probably too difficult to give the exact number, but I’ve found a
way to get a fair approximation which was verified in the following
way. I have calculated the real memory used, by the technique you will
see in the moment, and then have stopped the Apache server and saw
that the memory usage report indicated that the total used memory went
down by almost the same number I’ve calculated. Note that some
OSs do smart memory pages caching so you may not see the memory usage
decrease as soon as it actually happens when you quit the application.
This is a technique I’ve used:
For each process sum up the difference between shared and system
memory. To calculate a difference for a single process use:
use GTop; my = GTop->new->proc_mem(20984);
my = ->size - ->share; print "Difference is bytesn";
Now if we add the shared memory size of the process with maximum
shared memory, we will get all the memory that actually is being used
by all httpd processes, except for the parent process.
Finally, add the size of the parent process.
Please note that this might be incorrect for your system, so you use
this number on your own risk.
I’ve used this technique to display real memory usage in the module
Apache::VMonitor (see on of the previous articles), so instead of
trying to manually calculate this number you can use this module to do
it automatically. In fact, in the calculations used in this module
there is no separation between the parent and child processes; they
are all counted indifferently using the following code:
use GTop (); my = GTop->new; my = 0; my = 0; # @mod_perl_pids is initialized by Apache::Scoreboard, irrelevant here my @mod_perl_pids = some_code(); for my (@mod_perl_pids) my = ->proc_mem(); my = ->size(); my = ->share(); += - ; = if
So as you see, we accumulate the difference between the shared and reported memory:+= -;
and at the end add the biggest shared process size:my += ;
contains approximately the really used memory.
How do you find out if the code you write is shared between the
processes or not? The code should be shared, except where it is on a
memory page with variables that change. Some variables are read-only
in usage and never change. For example, if you have some variables
that use a lot of memory and you want them to be read-only. As you
know the variable becomes unshared when the process modifies its