Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Perl Not Releasing Memory

by rekcah (Initiate)
on Jul 02, 2003 at 06:57 UTC ( [id://270723]=perlquestion: print w/replies, xml ) Need Help??

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

I'm kind of new To Perl so bare with my idiocy and the simplicity of this script. The script tests number successivly to be prime or not. I will include the script bellow. Everytime I re-define a variable it seems to use a new chunk of memory. Is there a way I can prevent this for both $Divider and $Number. Or at least make it release the previously used memory. The script run for about 3 minutes then it starts using swap space Here It Is
#open(LOUTPUT,"lastoutput") or die "Unable To Open lastoutput File. #Please Ensure That This File Exists And Contains On One Line. This Fi +le #Must Only Contain Numbers"; #$number=<LOUTPUT>; $number=3; #close(LOUTPUT); $divisor = 2; test(); sub test() { # Un-Comment The Next Line For More Output #print("NUM=$number DIV=$divisor\n"); if ($number / $divisor == int($number / $divisor)) { # Number Is Prime if ($number == $divisor) { print("Prime $number\n"); # open(OUTPUT,">>output"); # print(OUTPUT "$number\n"); # close(OUTPUT); } # Number Is Not Prime $divisor = 2; $number = $number + 1; } $divisor = $divisor + 1; #sleep(1); test(); } # open(LOUTPUT,">lastoutput"); # print(LOUTPUT "$number"); # close(LOUTPUT);
Sorry its got lots of comments but it can do more than I want it to do for testing any help is greatly apreciated.

Replies are listed 'Best First'.
Re: Perl Not Releasing Memory
by antirice (Priest) on Jul 02, 2003 at 08:12 UTC

    Considering the sub is recursive and NEVER exits, is this really that surprising? The variables $number and $divisor are in the same address in memory the entire time (just print a ref to them and compare the addresses during every pass). The problem you are encountering is that a new call to the sub is getting pushed onto the internal stack with each call and never getting popped.

    antirice    
    The first rule of Perl club is - use Perl
    The
    ith rule of Perl club is - follow rule i - 1 for i > 1

Re: Perl Not Releasing Memory
by ant9000 (Monk) on Jul 02, 2003 at 08:17 UTC
    I simply fail to see why it shouldn't: you have no exit condition at all in your subroutine test, so it just gets on forever, eating up all the CPU and memory it finds until you block it... the problem is not Perl, just your code that's flawed. Try to read some of the Tutorials, if you don't feel at ease with Perl syntax; but never forget to look at your code!
Re: Perl Not Releasing Memory
by arthas (Hermit) on Jul 02, 2003 at 08:26 UTC

    Hi!

    It's not $Divider and $Number which eat up your memory (they're always the same variabile). The problem lies in the fact that your subroutine calls itself without a condition for doing that, causing and endless recursion.</p.

    Michele.

Re: Perl Not Releasing Memory
by Limbic~Region (Chancellor) on Jul 02, 2003 at 10:44 UTC
    rekcah,
    First, I would like to say Welcome to the Monastery and to Perl. Ok - everything everyone else has said is correct. There will be arguments on both sides on what I am about to say, but Perl was designed with deep roots in Unix - which originally didn't provide a mechanism to release memory back to the operating system. With this said, it is fairly adept at re-using memory without requesting more as long as the design of your program allows it to do its job. Future releases of Perl may even release memory back to the OS, but in the interim - lets fix your code. You will have to adapt it to your specific needs, but this should give you an idea.
    #!/usr/bin/perl -w use strict; for my $test_number (5 .. 1000) { next unless ($test_number % 2); my ($prime , $factor) = IsPrime($test_number); if ($prime) { print "$test_number is prime\n"; } else { print "$test_number is not prime - divisible by $factor\n"; } } sub IsPrime { my $input = shift; my $t_number = 3; while ($t_number < sqrt($input)) { return (0, $t_number) unless ($input % $t_number); $t_number += 2; } return 1; }

      There are faster ways to decide this problem, as well. I'm no mathematician, but your algorithm is dividing by all odd factors between 3 and sqrt(x); this can be improved by dividing by all *prime* factors between 3 and sqrt(x).

      Since you're already finding all these numbers, just use dynamic programming-- when you find a prime, hash it for later reference. Then in your loop just go through the keys of your hash.

        Anonymous Monk,
        As tilly would say, I am a displaced mathematician. I realize the inefficiency of the algorithm and I appreciate you pointing it out. In fact, the code itself could have been made a lot more concise by sacrificing readability. I was just trying to help the new monk out. I figured it was easy enough to understand and modify for their purposes.

        Cheers - L~R

Re: Perl Not Releasing Memory
by Elian (Parson) on Jul 02, 2003 at 13:55 UTC
    Ah, welcome to the wonderful world of programming languages without automatic tail call optimization. :)

    The problem is not that your variables keep grabbing more memory without releasing it--they aren't. The problem is that test() is calling itself recursively. Each call requires the allocation of a certain amount of stack space, which is released when the function exits, but in this case it never does so the call frames just pile up.

    Perl does do tail calls, just not automatic ones. Change that last test() into a goto &test and see if that doesn't make things much better.

Re: Perl Not Releasing Memory
by rekcah (Initiate) on Jul 02, 2003 at 17:32 UTC
    Thanks All For All The Help. It Still Uses A Lot Of Memory (Understandably) But It Does Use All Of The Mrmory In The Machine
    Thanks Again
    Stephen

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://270723]
Approved by allolex
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (5)
As of 2024-04-23 20:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found