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) | [reply] [d/l] |
Re: DESTROYing an object
by adrianh (Chancellor) on Dec 11, 2002 at 21:38 UTC
|
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. | [reply] [d/l] [select] |
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;
}
| [reply] [d/l] |
|
|
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
| [reply] [d/l] [select] |
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? | [reply] |
|
|
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". | [reply] [d/l] [select] |
|
|
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
| [reply] [d/l] |
|
|
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.
| [reply] |