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

Will calling DESTROY on an object cause it to be garbage-collected? Or will it simply call the DESTROY method and return?

Replies are listed 'Best First'.
Re: DESTROYing an object
by Ovid (Cardinal) on Dec 11, 2002 at 21:42 UTC

    DESTROY is merely a special subroutine that is called when an object goes out of scope, but right before it is garbage collected. DESTROY is merely a convenient way to have "cleanup" code executed when your object goes away. If you set up a blank DESTROY and called it, nothing would happen.

    package Foo; sub new { bless { test => 1 }, $_[0] } sub DESTROY {} package main; use Data::Dumper; my $foo = new Foo; print Dumper $foo; $foo->DESTROY; print Dumper $foo;

    Cheers,
    Ovid

    New address of my CGI Course.
    Silence is Evil (feel free to copy and distribute widely - note copyright text)

Re: DESTROYing an object
by adrianh (Chancellor) on Dec 11, 2002 at 21:38 UTC

    It will just call the destroy method and return. For example this:

    sub Foo::DESTROY { my $self = shift; print "destroying $self\n" }; my $foo = bless {}, "Foo"; $foo->DESTROY; print "foo is $foo\n";
    will produce
    destroying Foo=HASH(0x4759c) foo is Foo=HASH(0x4759c) destroying Foo=HASH(0x4759c)

    The first "destroying" comes from the explicit call to the method. The second by the method being called before the object is garbage collected.

Re: DESTROYing an object
by pg (Canon) on Dec 12, 2002 at 02:37 UTC
    We are looking at the wrong sequence of events. Calling DESTROY not subsequently involes garbage collector, on the contrary, it is the garbage collector will call the object's DESTROY method, if there is one defined, before it collect the 'garbage'.

    (A small quiz for everyone. Does the following two pieces of code cause memory leak? If not sure, test them with some system resourse monitor.)

    first one: while (1) { my $variable = \$variable; } second piece: define a class with this new: sub new { my $self = {}; $self->{"parent"} = $self; $self->{"child"} = $self; bless $self; return $self; }
      The first piece of code doesn't. In each iteration, a reference to an outer $variable is taken, and stored in the innter $variable. But the space for this variable is reused in the next iteration - it went out of scope at the end of the previous iteration.

      As for the second one, it depends. What else is there in the code? Each object created my this constructor will have two references to itself, so unless there's code to remove the self referentials, the objects will not be garbage collected before the end of the program. But that in itself isn't necessarely a memory leak.

      Abigail

Re: DESTROYing an object
by batkins (Chaplain) on Dec 12, 2002 at 03:09 UTC
    well, is there any way to force an object to be garbage-collected? or, to be more precise, is there any way to make a Tk::Photo or Tk::Image object free the memory it's using to store its image?
      You can't "force", because this only happens when you don't need any more the object! In other words, the garbage-collect only happens when the variable that holds the object goes out! To do that just rewrite the variable:
      undef $obj ; ## or: $obj = undef ; ## or: $obj = 123 ;
      But if you have another variable with the same content of $obj the garbage-collect doesn't happens!

      Some tests for DESTROY:

      ## This is for the main package, never do that! package main ; sub new { bless( {} , 'main') ;} sub hy { print "HELLO!\n" ;} sub DESTROY { print "DESTROY!\n" ;} my $obj = main->new ; # create the object. my $clone = $obj ; # save it in the clone. Comment this line # to see that the undef $obj works! print ">>$obj\n" ; # print the references. print ">>$clone\n" ; $obj->hy ; # test a method. undef $obj ; # lose the object. print "__END__\n" ; # End point! If you really lose # the object the DESTROY is called # before this print! Test to comment $clone.
      You asked for a way to free the memory used to hold the images. Don't forget that Perl, and generally any process in most OS, don't return the memory that it uses to the OS! Perl when clean the memory, it just clean it to be reused for new variables in the same process.

      Graciliano M. P.
      "The creativity is the expression of the liberty".

      You have to have all references to the object go out of scope. You can help this along by undefing the object reference.

      Perl's garbage collection system uses reference counts--so when nothing points to a piece of data, it can be garbage collected. Note that I said can. AFAIK, there is no way to force the issue.

      Check out this note in the perlobj document. Scroll up a bit to read the section on destructors. You might find it interesting, too.


      TGI says moo

        No need to force it. As soon as the count goes to 0, Perl attempts to get rid of it. This is immediate destruction with 3 exceptions that I know of. Those exceptions are bugs, cases where counts are not tabulated immediately (happens with map) and global destruction at the end of your program.