Date: Mon, 24 Sep 2001 20:23:26 +1000
From: mgjv@tradingpost.com.au (Martien Verbruggen)
Subject: Re: eval-statement fools garbage-collection ?
Message-Id: <slrn9qu2cu.8ai.mgjv@martien.heliotrope.home>

On Sun, 23 Sep 2001 20:32:43 +0200,
        peter pilsl <pilsl_@goldfisch.at> wrote:
> 
> I work with big anonymous structures and have the problem, that garbage 
> collection doesnt work. First I thought about circular references, but now 
> I found my problem:

> print `ps waux | grep mem.pl | grep -v grep | grep -v emacs`;
> my $ptr={};
> $ptr->{big}=[];
> $#{$ptr->{big}}=5000000;
> def2($ptr);
> print &{$ptr->{test}->{func2}}(5),"\n";
> print `ps waux | grep mem.pl | grep -v grep | grep -v emacs`;
> undef $ptr;
> print `ps waux | grep mem.pl | grep -v grep | grep -v emacs`;
> 
> sub def2 {
>   my $ptr=shift;
>   my $cmd='$ptr->{test}->{func2}=sub{return $_[0]+4};';
> #  $ptr->{test}->{func2}=sub{return $_[0]+4};
>   eval $cmd;
> }
> 
> 
> when running this way I get (skipped last column, the 5th column is the 
> size):
> pilsl    24212  0.0  1.0  2816 1288 pts/9    S    20:17   0:00 
> 9
> pilsl    24212  0.0 16.4 22356 20900 pts/9   S    20:17   0:00 
> pilsl    24212  0.0 16.4 22356 20904 pts/9   S    20:17   0:00 
> So the memory is *not* freed at the undef-statement ..

You don't know that. When memory is freed, it is not necessary for the
process to hand it back to the OS immediately, or at all. All it means
is that it is available to the application for subsequent requests for
memory.

On many Unix systems it is possible for programs to return memory to the
OS while still running (this has not always been the case on most
Unices), but it can only do that under certain circumstances, and it
most of the time as very little control over whether or not the OS gets
the memory back.

The message is: you cannot take the memory your OS reports a process to
be using, and equate the fact that it doesn't diminish to a memory leak.
One other possibility is that Perl has released the memory (freed it),
and for some reason the OS hasn't reclaimed it.

> When commenting the eval-statement in the def2-sub and uncomment the other 
> assignment, I get the following (expected result):
> 
> pilsl    24245  0.0  1.0  2820 1292 pts/9    S    20:21   0:00 
> 9
> pilsl    24245  0.0 16.4 22356 20900 pts/9   S    20:21   0:00 
> pilsl    24245  0.0  1.0  2824 1372 pts/9    S    20:21   0:00 
> So the mem is released at the undef-statement ...
> 
> this is strange ...

All you can conclude with certainty is that in the latter case the OS
has been able to reclaim the memory. 

Anyway, after all this digression: your code works fine for me under
Perl 5.6.1 on Linux kernel 2.2.16 with glibc 2.1.3, both with and
without the eval:

$ cat /tmp/foo.pl
#!/usr/local/bin/perl -w
use strict;

my $ptr={};
$#{$ptr->{big}}=5000000;
def2($ptr);
print $ptr->{test}->{func2}(5),"\n";
print `ps -o vsize,rss,args -p $$ | tail -1`;
undef $ptr;
print `ps -o vsize,rss,args -p $$ | tail -1`;

sub def2 {
    my $ptr=shift;
    my $cmd='$ptr->{test}->{func2}=sub{return $_[0]+4};';
    $ptr->{test}->{func2}=sub{return $_[0]+4};
    #eval $cmd;
}

$ /tmp/foo.pl
9
22000 20864 perl -w /tmp/foo.pl
 2468 1340 perl -w /tmp/foo.pl

$ vi /tmp/foo.pl # comment out 15, uncomment 16

$ /tmp/foo.pl
9
22000 20864 perl -w /tmp/foo.pl
 2468 1340 perl -w /tmp/foo.pl

One part of the perl config that may be of importance, but also may not
be:

$ perl -V | grep malloc
    alignbytes=4, usemymalloc=n, prototype=define
                  ^^^^^^^^^^^^^

What is your version of Perl?

Martien
-- 
Martien Verbruggen              | 
Interactive Media Division      | I took an IQ test and the results
Commercial Dynamics Pty. Ltd.   | were negative.
NSW, Australia                  | 


