State variable lifecycle when subroutine invoked via goto &sub
0 reputation · 13 Feb 2020, 21:46 UTC
0 reputation · 13 Feb 2020, 21:46 UTC
The goal is to determine the exact lifetime of a Perl 'state' variable when its containing subroutine is invoked repeatedly with 'goto &sub' instead of a normal call.
According to the documentation, a 'state' variable lives as long as the subroutine's symbol table remains loaded, and is freed when that symbol table is unloaded or the interpreter exits. However, 'goto &sub' replaces the caller's frame while leaving the callee's symbol table intact, so the associated state stash is not released during the program's execution.
This creates an unresolved decision: the language specification does not define whether the state stash should be considered eligible for reclamation while the subroutine remains in memory, nor does it provide an explicit way to reset or discard the variable in such a pattern.
Is the state stash eligible for garbage collection when the subroutine remains loaded but no further invocations occur via normal call?
Should developers treat state variables as effectively permanent when using 'goto &sub' in long-running loops, or is there a recommended practice to avoid unintended memory retention?
34775 reputation · 14 Feb 2020, 03:26 UTC
No. A Perl state variable is not eligible for reclamation merely because normal calls to its subroutine stop. While the subroutine's compiled code reference (CV) remains defined and reachable, its lexical pad and the state scalar stay allocated. goto &sub performs a tail call on the same CV; it does not create a new pad or free the existing one. In a long-running loop that repeatedly invokes the same subroutine through goto &sub, treat the state variable as effectively permanent.
state is available from Perl 5.10 onward.goto &sub replaces the caller's frame but reuses the callee's CV; it does not allocate a new subroutine or pad.state scalar lives in the CV pad.Perl reclaims storage by reference counting. Because a named subroutine remains reachable through its stash entry, or because a coderef is held elsewhere, the CV and its pad are not freed. The state scalar therefore survives for the life of the CV, not for the life of the most recent caller. If goto &sub targets a newly created anonymous subroutine each iteration, each CV has its own state variable, and prior storage can be reclaimed only when that earlier CV becomes unreachable.
This assumes Perl 5.10 or later and ordinary reference counting. A state scalar involved in a reference cycle may persist even after its CV appears dropped, until the cycle is broken. Behavior under threads or interpreter cloning is not addressed here.
perl -e 'print $]'Scalar::Util::refaddr(\&mysub) before and after several iterations; a stable address means the same pad and persistent state.state for per-iteration data. Pass an explicit accumulator or argument, or use a package variable or hash you control.undef &mysub or remove it from its stash while executing inside it via goto &sub.Is goto &sub aimed at one fixed named subroutine or stable coderef, or at a newly created anonymous subroutine each iteration? This changes whether prior state storage is collectable.
Read the state value across iterations. If the value persists and refaddr is unchanged, retention is caused by the same CV, not by the absence of normal calls. To test release safely, drop all references to the subroutine only when not executing it, define a new subroutine with the same name, and confirm that state initializes fresh.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.