in reply to Re: Safe.pm and memory problems
in thread Safe.pm and memory problems

Removing a module from memory can be as simple as undefing its symbol table like undef %strict::;

Unfortunately it doesn't work. See undef Package;.

--
Ilya Martynov, ilya@iponweb.net
CTO IPonWEB (UK) Ltd
Quality Perl Programming and Unix Support UK managed @ offshore prices - http://www.iponweb.net
Personal website - http://martynov.org

Replies are listed 'Best First'.
Safe.pm and memory problems - continue...
by shushu (Scribe) on Feb 16, 2003 at 12:45 UTC
    Hi Monks!
    I am coming back with questions about Safe.pm and memory handling, after reviewing the following messages:
    1. 'Displaying symbol tables for debugging' - and getting the symbol2 and packages subroutines from it.
    2. 'undef Package;' (156281) - and using Symbol delete_package subroutine.
    So I created a small script checking using the information gathered.
    The script uses Symbol.pm and Safe.pm, and include symbol2 and packages subroutines.
    All it does is execute a Perl script that uses a module (big module), and check the memory consumption.
    The script:
    use Safe; use Symbol qw(delete_package); use Data::Dumper; use strict; my $rc = 0; my $namespace = "SPACE"; my $CPT = new Safe($namespace); $CPT->deny_only(); my $file = shift; print "DEBUG - before rdo-\n"; system ("ps auxww|grep safe|grep -v grep"); print "-"x40,"\n"; <>; if (-f $file) { $CPT->rdo($file); } else { print "File \"$file\" does not exists !\n"; $rc = 1; } print "DEBUG - after rdo-\n"; print $@ if (defined $@); print "Printing \%SPACE::\n"; print Dumper \%SPACE::; print "Printing \%SPACE::INC\n"; print Dumper \%SPACE::INC; print "\nOutput from space_packages\n"; space_packages(); print "\nOutput from packages\n"; packages(); print "\nOutput from symbols2\n"; symbols2("SPACE"); system ("ps auxww|grep safe|grep -v grep"); print "-"x40,"\n"; <>; delete_package($namespace); print "DEBUG - after clearing namespace-\n"; print "Printing \%SPACE::\n"; print Dumper \%SPACE::; print "Printing \%SPACE::INC\n"; print Dumper \%SPACE::INC; print "\nOutput from space_packages\n"; space_packages(); print "\nOutput from packages\n"; packages(); print "\nOutput from symbols2\n"; symbols2("SPACE"); system ("ps auxww|grep safe|grep -v grep"); print "-"x40,"\n"; <>; sub space_packages { print "Packages: ", join(" ", grep /::$/, keys %SPACE::), "\n"; print " INC: ", join(" ", sort keys %SPACE::INC), "\n"; } sub packages { print "Packages: ", join(" ", grep /::$/, keys %::), "\n"; print " INC: ", join(" ", sort keys %INC), "\n"; } sub symbols2 { my $pkg = $_[0] || ''; no strict 'refs'; print "Symbols in ${pkg}::\n"; my $hash = *{$pkg.'::'}{HASH}; for (sort grep {!/::$|^_</} keys %$hash) { my $sym = $_; my $glob = $hash->{$_}; $sym =~ s/[[:cntrl:]]/'^' . chr(ord($&) + ord('@'))/ge; print " $sym (", *{$glob}{PACKAGE}, '::', *{$glob}{NAME}, "): "; if (defined $$_) { print "SCALAR='$$glob' "; }; for my $THING (qw(ARRAY HASH CODE IO)) { my $ref = *{$glob}{$THING}; if (defined $ref) { print "$THING=$ref "; } } print "\n"; } }
    The output (executed on Linux RH 7.3 with Perl 5.6.1):
    [root@gili /tmp]# perl safe.pl /tmp/safe2.pl DEBUG - before rdo- root 31983 0.0 1.6 3504 2068 pts/0 S 06:26 0:00 perl sa +fe.pl /tmp/safe2.pl ---------------------------------------- DEBUG - loading module momo- test DEBUG - after rdo- Printing %SPACE:: $VAR1 = { 'INC' => *SPACE::INC, '_' => *::_, 'a' => *SPACE::a, '_</tmp/safe2.pl' => *{'SPACE::_</tmp/safe2.pl'}, '__ANON__' => *SPACE::__ANON__, 'test' => *SPACE::test, 'momo::' => *{'SPACE::momo::'}, '_<momo.pm' => *{'SPACE::_<momo.pm'}, 'BEGIN' => *SPACE::BEGIN, 'main::' => *{'SPACE::main::'} }; Printing %SPACE::INC $VAR1 = { 'momo.pm' => 'momo.pm', '/tmp/safe2.pl' => '/tmp/safe2.pl' }; Output from space_packages Packages: momo:: main:: INC: /tmp/safe2.pl momo.pm Output from packages Packages: SPACE:: Opcode:: DB:: Data:: DynaLoader:: Exporter:: warning +s:: Symbol:: strict:: XSLoader:: attributes:: UNIVERSAL:: overload:: +<none>:: Safe:: subs:: IO:: Carp:: CORE:: main:: INC: Carp.pm Data/Dumper.pm Exporter.pm Exporter/Heavy.pm Opcode.pm +Safe.pm Symbol.pm XSLoader.pm overload.pm strict.pm subs.pm warnings. +pm warnings/register.pm Output from symbols2 Symbols in SPACE:: BEGIN (SPACE::BEGIN): INC (SPACE::INC): HASH=HASH(0x81945d8) _ (SPACE::_): SCALAR='_' ARRAY=ARRAY(0x819e1c8) __ANON__ (SPACE::__ANON__): a (SPACE::a): test (SPACE::test): CODE=CODE(0x819b320) root 31983 13.0 2.4 4500 3068 pts/0 S 06:26 0:00 perl sa +fe.pl /tmp/safe2.pl ---------------------------------------- DEBUG - after clearing namespace- Printing %SPACE:: $VAR1 = {}; Printing %SPACE::INC $VAR1 = {}; Output from space_packages Packages: INC: Output from packages Packages: Opcode:: DB:: Data:: DynaLoader:: Exporter:: warnings:: Symb +ol:: strict:: XSLoader:: attributes:: UNIVERSAL:: overload:: <none>:: + Safe:: subs:: IO:: Carp:: CORE:: main:: INC: Carp.pm Data/Dumper.pm Exporter.pm Exporter/Heavy.pm Opcode.pm +Safe.pm Symbol.pm XSLoader.pm overload.pm strict.pm subs.pm warnings. +pm warnings/register.pm Output from symbols2 Symbols in SPACE:: root 31983 0.8 2.4 4500 3068 pts/0 S 06:26 0:00 perl sa +fe.pl /tmp/safe2.pl ----------------------------------------
    What can we see here ?
    • The delete_package seems to work.
    • BUT - the memory consumption does not getting low.
    Any suggestions, except "fork" ?

    Thanks,
    shushu
      Hi again,
      Well, it all seems to be a matter of order.
      When deleting a package using Symbol::delete_package you should do it only after deleting packages used inside it. By executing packages() on SPACE namespace, executing delete_package on the packages used in it (except main::), and only after that executing it on the namespace itself - I got the answer.

      Thanks anyway,
      shushu