3.10 Cleaning Up Unused Objects with DESTROY


When a running program no longer needs a portion of computer memory, what happens to it? How is the program's memory managed? Various possibilities exist, and different languages handle the problem in different ways. For instance, the designer of the language can just leave the memory as it is, unused, and go on and use other memory for other tasks . No clean up is strictly necessary.

However, this might, and does, cause problems with certain kinds of programs. Some programs read in large amounts of data into their memory, perhaps extract some statistics on the data, and then go on to the next large chunk of data to repeat the same operation. A computer's memory is finite; for a program that runs a long time and examines a continuous source of data (say, for instance, the data generated by your sequencing facility), it will at some point use all available main memory.

It is necessary to consider how to clean up memory that is no longer used, so it can be reused by the program. This is sometimes called the garbage collection problem. Consideration of this problem has resulted in many approaches and a large amount of literature, which won't be discussed here.

However, sometimes there are practical considerations. In the class module Gene.pm , I'm keeping count of all objects that are created by the running program. In Perl, when a variable is no longer used, its memory is automatically cleaned up. One such instance is when a variable goes out of scope. For instance, in the following code fragment, the variable $i goes out of scope after the if block, and its memory is cleaned up, making it available to the rest of the program:

 if(1) {         my $i = 'ACCGGCCGGCCGGTTAATGCATAATC';         determine_function($i); } # $i has gone out of scope here 

This problem actually affects the Gene.pm module. Say you create a new object, and as the program continues, the object goes out of scope. For instance, if the object was created within a block, and the program leaves the block, the object is then out of scope. Perl will remove the part of memory that held the object, and all will be well... except that the global count of the number of objects will now be off by one!

What is needed is a way to automatically call a bit of code to adjust the global count whenever an object goes out of scope. Perl provides such a mechanism with the DESTROY subroutine. Perl calls the DESTROY method 1) if you've defined a method with that name in your class, and 2) a class object (a reference bless ed with the name of the class) goes out of scope. It does so automatically, just as AUTOLOAD is automatically called if you attempt to call a method that doesn't exist on a class object.

In our program, the only thing keeping track of when an object goes out of scope and is garbage collected by Perl is the global count of existing objects. This simple DESTROY subroutine will thus suffice:

 sub DESTROY {     my($self) = @_;     $self->_decr_count(  ); } 

Let's see if it works. Here's a test program, testGeneGC (GC for garbage collection):

 #!/usr/bin/perl # # Test the garbage collection of the Gene.pm module # use strict; use warnings; # Change this line to show the folder where you store Gene.pm use lib "/home/tisdall/MasteringPerlBio/development/lib"; use Gene; print "\nCount is ", Gene->get_count, "\n\n"; if(1) {     # Create first object     my $obj1 = Gene->new(             name                => "Gene1",             organism            => "Homo sapiens",     );               print "\nCount is ", Gene->get_count, "\n\n";          # Create second object     my $obj2 = Gene->new(             name                => "Gene2",             organism            => "Homo sapiens",     );           print "\nCount is ", Gene->get_count, "\n\n";          # Create a third object     my $obj3 = Gene->new(             name                => "Gene3",             organism            => "Homo sapiens",     );      print "\nCount is ", Gene->get_count, "\n\n"; } print "\nCount is ", Gene->get_count, "\n\n"; 

This produces an output that shows that once the three objects created in the scope of the if block go out of scope, the count is properly set back to zero:

 Count is 0 Count is 1 Count is 2 Count is 3 Count is 0 

As a further test, let's try taking the definition of the DESTROY subroutine out of Gene.pm . Now, try the test program testGeneGC to get the following output:

 Count is 0 Count is 1 Count is 2 Count is 3 Count is 3 

As you see, the last line still has a count of three Gene objects, when there are in reality none still within scope. To properly keep class-wide data on all objects, the DESTROY subroutine is sometimes a necessity.

For more details on DESTROY , including discussions of how to clean up more complicated data structures, see Section 3.14.



Mastering Perl for Bioinformatics
Mastering Perl for Bioinformatics
ISBN: 0596003072
EAN: 2147483647
Year: 2003
Pages: 156

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net