You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Bill Moseley <mo...@hank.org> on 2006/05/01 19:56:14 UTC
GTop vs. pmap on Linux
Apache/2.0.55 (Debian) mod_perl/2.0.2 Perl/v5.8.8
I'm testing out a Catalyst application running under mod_perl (was
using fastcgi before). I'm trying to get a grasp on the memory used
by the processes.
Anyone familiar with pmap on linux? There's this description of using
pmap to determine shared memory of a process:
http://virtualthreads.blogspot.com/2006/02/understanding-memory-usage-on-linux.html
But, I'm seeing different values from GTop. GTop is showing about 25M
shared, where pmap is only showing 5.7M shared.
I tend (and hope!) to believe GTop. But, now I'm wondering what's
the difference. Can anyone explain?
I'm also using a mmapped cache file for sessions. So, I'm not clear
how that is counted, if at all. Granted, it's not that big:
$ ls -lh /tmp/ws2_session-0
-rw-r----- 1 root root 5.6M 2006-05-01 07:05 /tmp/ws2_session-0
But I'm wondering if that's counted in the memory of each process,
and in GTop's shared count.
The other somewhat curious thing is that I'm not seeing any difference
in memory when I preload modules. Granted, I'm using Catalyst which
has a setup() method that brings in most code at module load time.
Do you think that accounts for the similar results below?
I'm preloading about 300 modules. (I just dumpped %INC for my tests.)
In this first test I'm using PerlLoadModule:
total = 905892K
shared = 0K
used = 845768K
free = 60124K
21229 size = 63008k
21229 vsize = 63008k
21229 resident = 44856k
21229 share = 24752k
21229 rss = 44856k
pmap -d 21229 | grep write
mapped: 63012K writeable/private: 39836K shared: 5752K
Loading 360 in startup.pl as "use Foo ();"
total = 905892K
shared = 0K
used = 865904K
free = 39988K
21873 size = 62936k
21873 vsize = 62936k
21873 resident = 44800k
21873 share = 24752k
21873 rss = 44800k
pmap -d 21873 | grep write
mapped: 62940K writeable/private: 39764K shared: 5752K
Only PerlLoadModule one module -- the main Catalyst application
module:
total = 905892K
shared = 0K
used = 857464K
free = 48428K
22024 size = 61628k
22024 vsize = 61628k
22024 resident = 43528k
22024 share = 24752k
22024 rss = 43528k
pmap -d 22024 | grep write
mapped: 61632K writeable/private: 38456K shared: 5752K
Not much difference.
--
Bill Moseley
moseley@hank.org
Re: GTop vs. pmap on Linux
Posted by Bill Moseley <mo...@hank.org>.
On Tue, May 02, 2006 at 10:00:20AM +0200, Torsten Foertsch wrote:
> For 2.4 kernel series the figures got from /proc/PID/statm are as valid as the
> figures from Linux::Smaps for kernels 2.6.14 and higher. For 2.6.0 up to
> 2.6.13 there is no way to count COW (shared by copy-on-write) pages. Since
> COW is the main way of sharing memory in a mod_perl environment figures that
> don't take these pages into account are useless.
Ok, I'm running 2.6.15 with 1GB.
I tried looking over the kernel source, but didn't get too far.
I realize I can't total up shared_* memory and have it mean anything
(since I don't really know which other processes it is shared with),
but can I total up private data and get an idea of the minimum
required virtual memory?
This prints out the values and totals them up at the end, which is not
very meaningful, but I'm curious about the private_* values:
$ perl smaps.pl `pidof apache2` (5 pids)
[...]
[9677]
size: 62028K
rss: 43140K
shared_clean: 4388K
shared_dirty: 18500K
private_clean: 0K
private_dirty: 20252K
[9675]
size: 56360K
rss: 38164K
shared_clean: 4472K
shared_dirty: 21144K
private_clean: 0K
private_dirty: 12548K
[totals]
size: 299780K
rss: 206820K
shared_clean: 20860K
shared_dirty: 97476K
private_clean: 0K
private_dirty: 88484K
Compare that to MySQL, which is statically linked on this machine:
$ perl smaps.pl `pidof mysqld--kernis` (21 pids)
[...]
[9265]
size: 145668K
rss: 36576K
shared_clean: 4040K
shared_dirty: 0K
private_clean: 0K
private_dirty: 32536K
[9264]
size: 145668K
rss: 36576K
shared_clean: 4040K
shared_dirty: 0K
private_clean: 0K
private_dirty: 32536K
[totals]
size: 3059028K
rss: 768096K
shared_clean: 84840K
shared_dirty: 0K
private_clean: 0K
private_dirty: 683256K
Looks like I don't want all those MySQL processes swapped in at the
same time.
Compare that with postgres on the same machine:
$ perl smaps.pl 28321 28322 28323 9681 9682 9683 9684
[...]
[9683]
size: 21248K
rss: 15164K
shared_clean: 2992K
shared_dirty: 8348K
private_clean: 0K
private_dirty: 3824K
[9684]
size: 21736K
rss: 15740K
shared_clean: 3780K
shared_dirty: 7732K
private_clean: 0K
private_dirty: 4228K
[totals]
size: 116744K
rss: 68432K
shared_clean: 19708K
shared_dirty: 33912K
private_clean: 0K
private_dirty: 14812K
--
Bill Moseley
moseley@hank.org
Re: GTop vs. pmap on Linux
Posted by Torsten Foertsch <to...@gmx.net>.
On Monday 01 May 2006 21:00, Perrin Harkins wrote:
> No. The current best bet is Linux::Smaps, which Apache2::SizeLimit now
> uses.
For 2.4 kernel series the figures got from /proc/PID/statm are as valid as the
figures from Linux::Smaps for kernels 2.6.14 and higher. For 2.6.0 up to
2.6.13 there is no way to count COW (shared by copy-on-write) pages. Since
COW is the main way of sharing memory in a mod_perl environment figures that
don't take these pages into account are useless.
But even with Linux::Smaps a problem remains when swapping/paging is allowed.
When a page is erased from memory and lives only in swap space there is no
other way on Linux to determine to how many processes it belongs than to page
it in. And this is certainly to much overhead only for that.
To overcome this problem either disable all swap space or put these lines into
your startup.pl:
------------ %< -------------------------------
require 'syscall.ph';
require 'sys/mmap.ph';
0==syscall &SYS_mlockall, &MCL_CURRENT | &MCL_FUTURE
or die "ERROR: mlockall failed: $!\n";
------------ %< -------------------------------
or a little shorter:
------------ %< -------------------------------
0==syscall 152, 3 or die "ERROR: mlockall failed: $!\n";
------------ %< -------------------------------
This locks the parent apache completely into memory making it unpageable. The
worker processes remain pageable. Now you waste a few megabytes of main
memory but since the parent process is completely in core and, hence, all
shared portions are so as well the private memory for each child is correctly
determined by counting private pages plus swapped pages. This can be done by
reading /proc/PID/smaps for >=2.6.14 or by reading /proc/PID/statm for 2.4.x.
Torsten
Re: GTop vs. pmap on Linux
Posted by Perrin Harkins <pe...@elem.com>.
On Mon, 2006-05-01 at 10:56 -0700, Bill Moseley wrote:
> Anyone familiar with pmap on linux?
No. The current best bet is Linux::Smaps, which Apache2::SizeLimit now
uses.
> I tend (and hope!) to believe GTop.
Don't believe it. It's probably getting the same numbers you'd get
from /proc/self/statm, and not accounting for copy-on-write well. There
was a lot of discussion about this a few months back on the list.
> I'm also using a mmapped cache file for sessions.
That probably affects GTop, but I couldn't say for sure.
> The other somewhat curious thing is that I'm not seeing any difference
> in memory when I preload modules. Granted, I'm using Catalyst which
> has a setup() method that brings in most code at module load time.
> Do you think that accounts for the similar results below?
Probably. Try dumping %INC at the end of your startup.pl when you don't
preload. If the list is similar, that would account for it.
One simple approach for memory tuning that avoids all of these issues is
to just look at the output of "free." That will show you how much real
memory is unused. If your tuning is working, that should be going up.
- Perrin