Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

"goto" memory leak

by jethro (Monsignor)
on Mar 29, 2016 at 16:35 UTC ( #1159029=perlquestion: print w/replies, xml ) Need Help??

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

Hi, just found a really simple memory leak:
#!/usr/bin/perl again: my $h; goto again;

I only could test it on perl5.18.2 and 5.20.2. Since it is so trivial/universal, I really suspect this is already widely known, but I couldn't find it mentioned in the perldeltas or on rt.perl.org.

If not, could someone with an up-to-date version of perl test this snippet and forgive me for not wanting to install the newest perl just for this quick check (just run it and look what "top" says, the leak is immediately evident).

Replies are listed 'Best First'.
Re: "goto" memory leak
by Anonymous Monk on Mar 29, 2016 at 17:33 UTC
Re: "goto" memory leak
by dave_the_m (Monsignor) on Mar 30, 2016 at 08:52 UTC
    Strictly speaking, it's a not a leak: the memory is reclaimed on scope exit. This code doesn't grow in memory usage after the first iteration of the while loop:
    while (1) { $i = 0; again: my $x; goto again if $i++ < 100_000_000; }
    Part of the run-time action of 'my' is to make a note to free the lexical at scope exit. The goto causes additional notes to be pushed on the savestack without any scope being exited. When the scope is finally exited, all the notes are popped off the savestack and processed.

    Dave.

      That depends on how you define "memory leak".

      At least under Wikipedias definition ("In computer science, a memory leak is a type of resource leak that occurs when a computer program incorrectly manages memory allocations1 in such a way that memory which is no longer needed is not released.") this still is a leak. Because the main scope is never exited (while the program is running) there is at least one scope that never releases its memory.

      And then there are closures. See the following code that also exhibits the memory leak:

      #!/usr/bin/perl my $i; top: while (1) { again: my $x; $i = 0; goto again if $i++ < 100_000; } goto top;

      Necessarily the hook variable has to be in the main scope (I assume), but the interesting thing is that the code seems to be minimal for the closure case, i.e. $i creates the closure, but $x is needed to create the leak.

      UPDATE:Anon Monk found a silly mistake in my code, the inner goto is an endless loop. The conclusion is wrong, I tested closures with teh following code and memory stayed low.

      sub closure { my $s; return sub { $s=5; my $i; } } my $f = closure(); while (1) { $f->(); }

        there is at least one scope that never releases its memory.

        In your original program, yes. It never releases memory, but that memory is still needed. That doesn't meet the definition of a leak.

        Keep in mind that the run-time effect of

        my $i;
        is similar to
        Hook::Scope::POST(sub { $i = undef });

        It pushes an instruction on the stack to clear the scope on exit (which could happen, say, if an exception occurs).

        That snippet exhibits an infinite loop, or two. The goto is always taken since $i++ < 100_000 will always be true...

        Objects may have side effects when they are DESTROYed, so this must happen at some well-defined moment (scope exit). Gotos cannot create scopes as there is no way to determine the flow of the program.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1159029]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (6)
As of 2020-10-30 13:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My favourite web site is:












    Results (279 votes). Check out past polls.

    Notices?