http://qs321.pair.com?node_id=1159109


in reply to Re: "goto" memory leak
in thread "goto" memory leak

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->(); }

Replies are listed 'Best First'.
Re^3: "goto" memory leak
by ikegami (Patriarch) on Mar 30, 2016 at 13:15 UTC

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

      Ok, but again we could argue over the definition of the word "needed". "Needed" by the program writer or "needed" by an implementation that keeps scopes around that are not accessible to the program writer anymore? EDIT: Ok, POST is a way to actually access such scopes, maybe even other introspection code, but the question is whether there is a need to create and keep these scopes at all when the writer does not indicate he wants them around?

      I'm more than happy with renaming the problem to "goto creates spurious scopes". The question that I can't answer is whether "goto" does that for a good reason, like "goto is harmful, and has to do this to jump in and out of nearly arbitrary scopes", or that it really is a bug.

        "goto creates spurious scopes".
        No, goto doesn't create scopes, spurious or otherwise. There aren't any hidden or misbehaving scopes here. It's a bit like the following code:
        while (1) { $i = 0; my @a; again: push @a, 1; goto again if $i++ < 1000; }
        In that code, there are only two scopes: the implied whole-file scope, and the while loop. The array will repeatedly have 1000 elements pushed on it, then be emptied.

        The goto just moves execution around to various places within the one scope.

        Perhaps the confusion is seeing 'my' as just a compiler declaration, like 'int' is in C; it's not; its something that has a runtime effect as well as a compile-time effect. If you repeatedly execute the 'my' without ever leaving the scope which that 'my' is embedded in, then that runtime effect will accumulate.

        Dave.

        I'm more than happy with renaming the problem to "goto creates spurious scopes".

        goto doesn't create any scopes. As I've already stated, the memory is being used when my is executed since that causes it push an instruction on the stack.

        Ok, but again we could argue over the definition of the word "needed". "Needed" by the program writer or "needed" by an implementation that keeps scopes around that are not accessible to the program writer anymore?

        The instruction is needed because it's virtually impossible to tell that the scope will never exit.

        • A lot of things can throw exceptions.
        • Including signal handlers.
        • The program can change while it's running.

        Even in the simplest cases, it would be extremely expensive to check, especially since this check would have to be performed at run-time.

Re^3: "goto" memory leak
by Anonymous Monk on Mar 30, 2016 at 19:26 UTC

    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.