Mastering Perl for Bioinformatics [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Mastering Perl for Bioinformatics [Electronic resources] - نسخه متنی

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید










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 blessed
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.


/ 156