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

Until now all of my Perl scripts have delt with smallish arrays and smallish hashes. Now I have need to run a script which will work on a few largish arrays.
I do not need all of the arrays at once, hence I can undef an array after I am done with it then move on to the next array.

I'm wondering if the undef is the best way to "throw out" the old array.

And I'm wondering if this will free the memory for subsequent use.

Sorry if the question is a bit odd but I have used languages in the past which did not handle freeing of memory properly and I'd rather not find out by hitting a brick wall when I scale later.

Also how many elements are you talking about? I have to ask because one of my partners was concerned about the same thing and he had 100 elements? ;)

Many machines these days have tons of ram and it quickly recovers stuff once a job completes. So it is good to be clean but don't get too freeked out unless of course you have gigantic arrays and hashes.

I believe my arrays will be limited to 10,000 or less.
Normally I wouldn't be concerned because I've never seen a problem with Perl on a Linux box holding ram after the job completes. I don't know if this is to the credit of Linux or Perl or both. But so far once the job completes it looks like all ram is returned.

However since I'll be using a couple of dozen 10,000+ arrays one after the other during the same job I was concerned about memory during the job.

you have to distinguish between "free memory" that is available to the Perl process and "free memory" that is available to the operating system. A simple undef will not free the memory for the OS, but that for perl only.

Let's say your box has 128MB RAM. You start some perl script . The perl process takes something between 5 to 6MB of RAM. Now you create some hash of 10MB size. Your process now takes 16MB of RAM. Now you undef the hash again. Your process still takes 16MB of ram.

Now you - in the same process - create some 5MB list/array/whatever. Your process still takes 16MB of RAM. So perl keeps always the memory that was allocated at max.

Subsequent allocations within this memory are handled by perl itself and not by the OS, thus the process doesn't grow in memory as long as you don't allocate more than was allocated at max. at any time before by the current perl process.

So what can one do against that? Under Linux or some
other superior OS that has fork - yes you got it: dealocate the big array and just fork. More precisely spawn and let the parent process die.

Forking after using the array (regardless whether you
undef it first) only makes the problem worse, now you
have doubled the memory usage. Letting the parent die
just makes you back at the previous memory usage.

There is a "famous" trick, used by long running processes
to prevent possible memory leakage from sucking up all the
resources, but that doesn't use fork, it uses
exec. execing yourself means that
you are restarting yourself - starting with a fresh sheet
of memory. Obviously, this is not going to work for many
programs.

Of course, this example is OS dependant. But you can notice that the first solution does not free any OS memory at all. As FatVamp said, Perl can then reuse the memory. It can be noticed that a few more memory is freed when using undef, but not all that was used.

Except this isn't entirely true--perl doesn't release the memory used for the array itself, though the memory for the scalars is released. If you want an array's memory released, you do have to undef it.

Yes, undef is the best way to completely release the memory that an array uses. That memory will be available for reallocation in your program. The memory will not, unless the array is very large and you're using an OS or version of libc that supports it, be released back to system.

In this case, where your array is 10K elements or so, it's probably not worth it. That's only using 40K of memory, which really isn't that much.

When putting a smiley right before a closing parenthesis, do you:

Use two parentheses: (Like this: :) )
Use one parenthesis: (Like this: :)
Reverse direction of the smiley: (Like this: (: )
Use angle/square brackets instead of parentheses
Use C-style commenting to set the smiley off from the closing parenthesis
Make the smiley a dunce: (:>
I disapprove of emoticons
Other