As h0mee and I were playing pool last night, the topic came up of perl's garbage collection system -- of which, I asked him this question:*

Why does perl's GC system not re-allocate the memory that a given lexically scoped variable consumes when said variable goes out of scope?

Pondering Automagical De-allocation of Memory:

We decided that it would be prohibitively difficult and possibly pretty dangerous (as far as perl having to allocate memory to the same variable another time, after re-claiming the memory), because perl would have to guarantee that the variable would never be mentioned again, much like the time redmist caused the "incident" at Thanksgiving.

I thought about this, and then thought of what I had read on page 56 of Camel 3, earlier in the day about name lookups. A name lookup occurs whenever you declare a variable with my or our. (So sayeth Camel 3...if a name lookup occurs any other time, lemme know.) The five rules regarding name lookups on that page (basically) say that when a variable is declared within a scope, perl looks in a bunch of places (outside the block (if any -- and outside the second block, if any, and so forth). After it is done looking through the code blocks, perl takes a look at the compilation unit. Whether this is an eval()**, or the file itself (i.e. not in any block at all (unless you consider the file itself a block)). If a variable is declared twice, an error is raised.

And so+, perl tries to find another variable of the same name. Why couldn't perl use a similar process to decide whether there was any name-dropping of the variable in question outside the variable's scope, and/or any process that would involve coming back to said scope? There is one problem that my mal-developed eyes can see:

This idea would most likely necessitate some pretty major changes in perl's GC system (that was most likely a very large understatement). Perl internals gurus: feel free to comment.

Why Not Give The Programmer a Little freedom?

Then, we thought, the programmer would probably have a better idea of which variables he wanted to throw away. Why not provide perl with a builtin free function? Some would argue that it would make the feet much more shootable. Although h0mee and I disagree with that argument, and propose that there are lots of ways to shoot yourself in the foot. There are two ways that I know of to make the feet more bullet resistant:

The pragma could be called risk, which would allow free to be used. The programmer could de-allocate memory if (s)he was certain that the corresponding variable would never be mentioned again. If perl removed the variable from the symbol table, and by some code-related fumble of grandiose proportions, the variable was named again, it would raise an error under the strict pragma.

But enough of this hypothetical mumbo-jumbo! Who cares? Well, I was hoping to spawn some interesting conversation about Perl internals.++ Kind of a round about way to do it, but what the hell? Who knows, maybe some good will come of it.

So is this possible? Is it wise? What do you think? </p * Yes, I do mean perl. Follow this link for an explanation.
** With eval() EXPR, the "edges" of the *contents* of EXPR act as curlies.
+ There are some more actions that perl takes to find another variable of the same name, but they are not germane to our current exchange...although there is no guarantee that the preceding information above was relavant either.
++ And maybe how much I suck at understanding perl's guts.

Replies are listed 'Best First'.
Re: free 0x010400!
by AgentM (Curate) on Jan 24, 2001 at 01:42 UTC
    After reading perlxs, perlxstut, and perlguts, you'll find that this is entirely possible. By decrementing the "pointer" field of any var to 0, the garbage collector will come by and nuke it. This is entirely possible in Perl, thanks to the wonderful Inline module. This is not adviseable since accessing a variable which has been nuked by the garbage collector (not possible in Perl alone) will result in "undefined" behavior.

    Another method is to call one of the perlxs' free commands which will nuke the var immediately. But be warned, using such functionality may result in a debugging nightmare. In short, I don't see this as overly useful. Especially in OO software, where I WANT the object to go out of scope and call a DESTROY block, I don't see a need for free(). I see this as just a nother reason perl is cool. If you really want to know when something is gone, put it into scope. This is the most obvious and reasonable use for a scope. using well-designed scopes will save on memory as well as on debugging time, so you have a win-win situation. (use risk;? funny! ) I find that perl provides enough freedom as it is! :-D

    AgentM Systems nor Nasca Enterprises nor Bone::Easy nor Macperl is responsible for the comments made by AgentM. Remember, you can build any logical system with NOR.
(tye)Re: free 0x010400!
by tye (Sage) on Jan 24, 2001 at 02:00 UTC

    When lexicals are destroyed, their space isn't free()d (their value isn't reset either, but that is just to be lazy). This goes along with Perl's general theory of sacrificing memory for speed.

    I believe that you can already override this by simply using undef on your lexical. No need for some fancy module.

            - tye (but my friends call me "Tye")
      I read some node (sorry, no URL) earlier today in which, it stated that when you undef a variable, it does free up space, but it frees it to perl, not to the OS. This means that in the snippet:
      my $foo = "I drank too much Dew."; undef $foo; my $bar = "I drank too much Dew.";
      Perl will allocate to $bar the memory that $foo took up prior to $foo's undef'ing (or Moral Equivalent).

      redmist
      Silicon Cowboy
      redmist::webnode

      OK, I am a silly goober. Apparently free does NOT give memory back to the OS. It just throws it back n the heap. There goes *that* idea.