in reply to Re: releasing memory from a loop in Windows
in thread releasing memory from a loop in Windows

First of all, Perl doesn't use garbage collection — it uses reference counting — so to say @data is *garbage collected* is wrong. Use the more general term *freed* instead.

The general rule is that variables are freed at the end of the scope in which they are declared, and new ones are created the next time the scope is entered. In this case, the end of the scope is the end of the loop pass. (It is not the end of the loop.) That means @data gets freed at the end of every loop pass, so there is no accumulation of memory use. There's an optimization at play, but it is of no consequence.

The exception is when a reference to a variable survives the scope in which the variable is declared. In the following, @data and its contents are NOT freed at the end of every loop pass, because a reference to the array survives the loop.

my %all_files; foreach my $file (@files) { open(my $fh, "<", $file); my @data = <$fh>; $all_files{$file} = \@data; close($fh); }

By the way, the close($fh) is redundant, since freeing $fh closes the file handle.

Caveat

To speed things up, Perl loops free the contents of variables instead of freeing the variables themselves at the end of every loop pass. This is completely transparent and does not use up any extra memory. In this case, it means

foreach my $file (@files) { open(my $fh, "<", $file; my @data = <$fh>; close($fh); }

is equivalent to

{ my @file; my $fh; foreach my $file (@files) { open($fh, "<", $file); @data = <$fh>; close($fh); undef $fh; # Frees $fh's content. undef @data; # Frees @data's content. } }

Replies are listed 'Best First'.
Re^3: releasing memory from a loop in Windows
by Jenda (Abbot) on Aug 07, 2006 at 21:47 UTC

    IMHO it uses "reference counting garbage collection". You don't have to allocate and deallocate memory, do you? I don't see why would the term "garbage collection" be used only for the "mark&sweep" and "copying" types.

    Except maybe that Microsoft, for marketing purposes, wanted people to believe .Net has something old VB did not have. So instead of saying that .Net has a mark&sweep garbage collector, while VB used a reference counting one, they want everyone to think, .Net has garbage collection, while VB did not.

      It's not just your opinion that considers "reference counting" as just one of several methods of implementing "gargabe collection", and the trend for Perlists to disown the term "garbage collection" as false elitism.

      See wikipedia "Reference counting" where the first application of "Reference counting" is "Garbage collection".

      See also Wikipedia "Garbage collection"/"Reference counting" where RCGC is contrasted with "Tracing GC".

      See also Wikipedia "Garbage Collection"/"Implementations" where is says:

      Script languages like Perl, Ruby, Python and PHP tend to have built-in support of GC.

      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

        The Wikipedia articles are confusing and/or very vague. "Garbage collection (computer science)" defines garbage collection as "a form of automatic memory management." (The rest of the article is about garbage collectors.) The same article also calls reference counting a form of automatic memory management.

        "The garbage collector attempts to reclaim garbage, or memory used by objects that will never again be accessed or mutated by the application." further confuses the issue, since garbage never exists in Perl according to that definition. The memory is freed as the point where it would become garbage.

        But that's all irrelevant here. It's clear it considers reference counting a type of garbage collection. I was led to believe GC refered specifically to asynchronous memory reclamation, but that's apparently false. My post has been corrected.