dpuu has asked for the wisdom of the Perl Monks concerning the following question:

Is there a standard way to find out how much memory a perl process is using? On a Linux box, I'm currently using:
sub get_memory_used { my $result; open STAT, "</proc/$$/status" or die "can't open ...: $!"; while (<STAT>) { /^VmSize.*?(\d+) kB/ or next; $result = $1; last; } close STAT; defined($result) or die "can't find memory used"; return $result * 1024; }
but this doesn't feel very portable. --Dave

Replies are listed 'Best First'.
Re: get memory usage
by Zaxo (Archbishop) on Aug 24, 2002 at 00:33 UTC

    If perl is compiled with DEBUGGING_MSTATS set, Devel::Peek::mstat("Some Tag") will dump memory stats.

    After Compline,
    Zaxo

Re: get memory usage
by RMGir (Prior) on Aug 24, 2002 at 00:30 UTC
    It's not a very portable problem, unfortunately.

    Check out Proc::ProcessTable; it will give you memory usage for different platforms. But even with that, the key for memory usage changes on many oses.

    Your best bet is probably using /proc, as you are now; that's fairly portable these days, at least on Unices. Not MacOSX, though. (Edit: As sauoq points out below, proc's internals aren't portable, though.)

    For an example of using proc on another OS, check out Solaris::ProcFS.
    --
    Mike

      Your best bet is probably using /proc, as you are now; that's fairly portable these days, at least on Unices.

      Unfortunately, that just isn't true. Even among systems that have /proc, the format is often very different.

      -sauoq
      "My two cents aren't worth a dime.";
      
Re: get memory usage
by perrin (Chancellor) on Aug 24, 2002 at 06:08 UTC
    Take a look at how Apache::SizeLimit and Apache::GTopLimit do it.
      hehe looks like they ran into the same issue... (code from Apache::SizeLimit)
      BEGIN { # decide at compile time how to check for a process' memory size. if (($Config{'osname'} eq 'solaris') && ($Config{'osvers'} >= 2.6)) { $HOW_BIG_IS_IT = \&solaris_2_6_size_check; } elsif ($Config{'osname'} eq 'linux') { $HOW_BIG_IS_IT = \&linux_size_check; } elsif ($Config{'osname'} =~ /(bsd|aix)/i) { # will getrusage work on all BSDs? I should hope so. if (eval("require BSD::Resource;")) { $HOW_BIG_IS_IT = \&bsd_size_check; } else { die "you must install BSD::Resource for Apache::SizeLimit to w +ork on your platform."; } } else { die "Apache::SizeLimit not implemented on your platform."; } }


      -Waswas
        Right. There's no portable way to do it. Apache::GTopLimit uses a library from the Gnome project to abstract it, but it's harder to install because of that.
Re: get memory usage
by zentara (Cardinal) on Aug 25, 2002 at 17:45 UTC
    This nifty little sub was posted awhile back on this subject
    #!/usr/bin/perl -w use strict; #by rob au print join("\n", &memusage), "\n"; exit 0; # memusage subroutine # usage: memusage [processid] # this subroutine takes only one parameter, the process id for # which memory usage information is to be returned. If # undefined, the current process id is assumed. # Returns array of two values, raw process memory size and # percentage memory utilisation, in this order. Returns # undefined if these values cannot be determined. sub memusage { use Proc::ProcessTable; my @results; my $pid = (defined($_[0])) ? $_[0] : $$; my $proc = Proc::ProcessTable->new; my %fields = map { $_ => 1 } $proc->fields; return undef unless exists $fields{'pid'}; foreach (@{$proc->table}) { if ($_->pid eq $pid) { push (@results, $_->size) if exists $fields{'size'}; push (@results, $_->pctmem) if exists $fields{'pctmem'}; }; }; return @results; }