Re: BEGIN initialization and memory
by blokhead (Monsignor) on Jul 23, 2003 at 06:47 UTC
|
Perl never reclaims used memory to your operating system during the course of your program. It keeps it allocated until the process ends. In the case of mod_perl, the Perl process runs as long as Apache runs, so you won't be able to "give back" memory to the OS. Update: I stand corrected. See BrowserUK's reply below.
However, the lexical scope of BEGIN blocks is the same as any other block, so the garbage collection will have the same effect as any other block structure. Unfortunately for you in this case, Perl's named subs are not lexically scoped, and can't be "cleaned up" as such.
You could however use anonymous subs, which can be scoped and cleaned up lexically, or you could clear out the symbol table entry for subs you declare in the BEGIN block. It's my understanding that doing either of these would trigger garbage collection for the subs. Their memory would be recliamed by Perl but not by the OS. In these cases, Perl would reuse the memory later, so it might still be a solution to your memory concerns.
blokhead
| [reply] |
|
|
Perl never reclaims used memory to your operating system during the course of your program.
According to the man that knows, this isn't exactly so, as he explained here.
You can actually what this happen in Win32 if you monitor memory usage with the task manager and type the following
P:\test>perl58 -de1
Loading DB routines from perl5db.pl version 1.19
Editor support available.
Enter h or `h h' for help, or `perldoc perldebug' for more help.
main::(-e:1): 1
DB<1> ;{ $s = 'X' x 30_000_000 }
DB<2>
After entering that line into the debugger, I can watch the memory for the task grow to close 100 MB, and then fall most of the way back to the 4 MB that it started out as, as $s goes out of scope and its memory is returned to the OS.
You could probably do something similar using top under *nix.
Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
| [reply] [d/l] |
|
|
| [reply] |
|
|
|
|
one note though, in your example you are allocating one huge block, in most live programs they dont presize arrays or hashes and end up growing them with a loop. in those cases the memory will most likly never be released. So in most cases it is safe to think about the memory, once allocated, being stuck allocated to your running program.
-Waswas
| [reply] |
|
|
|
|
| [reply] [d/l] |
Re: BEGIN initialization and memory
by aquarium (Curate) on Jul 23, 2003 at 21:59 UTC
|
I believe it does make sense that an initialization routine (inside BEGIN) block actually keeps the variables hanging around, otherwise you wouldn't have initialized variables, would you? | [reply] |
|
|
BEGIN
{
my $x = 'foo';
}
Outside of the block, would you expect to see a variable named $x? Would you expect it to have a value?
In fact, it doesn't, because the normal lexical scoping rules apply. BEGIN isn't extra special magic in that variables leak out. It's just a normal block that happens to execute at a special time. | [reply] [d/l] [select] |
|
|
| [reply] |