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

Hi, I'm having a doubt regardng Garbage Collection in perl. Please have look at the piece of code given below.
package UserScript; sub Process { my (@List); $List[0] = FormData("George",70); $List[1] = FormData("Mike",54); $List[2] = FormData("Crieg",37); } sub FormData { my($UserData) = {}; $UserData->{name} = $_[0]; $UserData->{Age} = $_[1]; # Doing some processing. return $UserData; }
One Perl interpreter instance will be created in C code and the subroutine Process will be called many times. My questions is what will happen to the memory allocated by the subroutine FormData?. I think all the memory allocated by the subroutine FormData will not be freed across the calls to the subroutine Procees and destroyed only when the perl Interpreter instance is destroyed ( When the C program Exits). Is there any way to free the memory allocated by the subroutine FormData when the subroutine Process exits every time. Thanks.

Replies are listed 'Best First'.
Re: Garbage Collection
by Fastolfe (Vicar) on Jan 05, 2001 at 19:59 UTC
    Since @List is scoped within Process, it will be destroyed when Process exits (unless you do something with the "return value" of Process, which will be the right-hand-side of your last assignment: a single FormData item), which will destroy every element of the array in the process. Perl keeps its own reference count of each variable, even if it's nested within another. When FormData exits, $UserData is destroyed, but the data it was pointing to gets allocated into a @List element, so the reference count goes from 1 to 2 to 1 (or maybe just 1 -> 1; I'm no expert). When your first function terminates, @List is destroyed, dropping the reference counts for each of its elements to 0, causing them to be reaped in turn as well.

    Remember that resources aren't literally free()'d, they're just returned to the pool for other Perl variables to use as needed. You cannot "release" memory consumed by now-unused variables back to the OS. See How can I free an array or hash so my program shrinks?.

Re: Garbage Collection
by mrmick (Curate) on Jan 05, 2001 at 19:27 UTC
    Here's another shot at it...

    Memory allocation is limited to scope(block,subroutine,package). If you have any references to an object then the object stays in memory. Once the last reference to that object is gone (out of scope or undef'd for example) then your resources are freed automatically.

    The data(object) is persistent only when you have something in the namespace(s) that reference.

    Mick
Re (tilly) 1: Garbage Collection
by tilly (Archbishop) on Jan 05, 2001 at 20:16 UTC
    The Perl interpreter uses reference counting. When @List is freed, then the scalars in it have reference counts decremented. Since there are no other references to it, at that point it knows to free the data structures in FormData and cheerfully does so.
Re: Garbage Collection
by ChOas (Curate) on Jan 05, 2001 at 19:18 UTC
    Eeehm I'm not sure if I understand you, but here is a shot:
    As long as you don't reference to yourself there won't be any
    problem in any Perl version (afaik)
    Memory WILL be freed by the garbage collector back to the
    program that allocated it

    GreetZ!,
      ChOas

    print "profeth still\n" if /bird|devil/;
Re: Garbage Collection
by kschwab (Vicar) on Jan 05, 2001 at 19:24 UTC
    Since none of the variables in your FormData sub are global, they will go out of scope when the sub returns. If you are, however, wanting to free global vars that don't go out of scope, see undef() and/or delete().

    I think the: "How can I free an array or hash so my program shrinks?" section of the Perl faq covers this.