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

Hi Monks,

I'm a newbie perl programmer. Sorry for my mistakes and for my English.

I'm developing a degree project to process a lot of data in real time, about 10 database records /sec. The aplication it's in a infinite loop that takes 10 records an process its inserting the results in another table.

I'm usign PostgresSQL 7.1.3 in a RedHat 7.2 (kernel 2.4.9-13enterprise) with DBD::Pg and DBI. My perl version is "v5.6.0 built for i386-linux". Another CPAN modules I'm usign are: Proc::Daemon, Data::Dumper (Only for debugging an loging purposes), GSM::SMS (Application core, with own modifications).

Monitorizing the app I can see that it eats a lot of memory, about 200MB (TOP INFO: SIZE 224M RSS 224M SHARE 1928 )after 30 min. and more. After reading some docs about perl and system malloc I'm a bit confusing, what it's better? now I have perl -V:d_mymalloc = undef.

Any Idea ?, In a production state I need about 5 app instance running in the same machine and then memory consumption would be a hard handicap.

Thanks

Replies are listed 'Best First'.
Re: Perl memory Memory consumption
by jeroenes (Priest) on Nov 22, 2001 at 20:06 UTC
    First of all, without specifics it's hard to give you any but general advice. With specifics I mean, how does your perlcode look like?

    Perl is a memory eater. But in my experience you only get to these huge amounts of memory footprint if you have large data structures holding small items. Eg, a million array items of one byte will take 43 Mb of memory. Array but more so hash overhead is large.

    To me it sounds like you are trying to rebuild your PostgreSQL database in perl memory. That would be a bad idea. If this is the case and if you did so because Postgres communication is too slow (I doubt that with 10/s) move to a faster system, like BerkeleyDB (www.sleepycat.com).

    About the malloc system, perl normally comes with its own. If you want to know more about it, read perlguts.

    HTH,

    Jeroen
    "We are not alone"(FZ)

      Hi,

      Thanks for your observations, but due to a NDA in my project I can't publish any code. But looking the memory consumption I can see that it grows about 1 MB/sec. I think the problem is in this part :
      	my $config = Config->new(config_file => "config.xml", debug=>0);
      
      
      
      
      
      	$bd =  db_out->new ($config->{db_data});
      
      
      
      
      
      	while (1) { 
      
      
      
      
      
        		$records = $bd->stack_out_get(0);
      
      
      
      
      
        		if(defined($records)) {
      
      
      
      
      
          			while (($key,$msg)= each %$msg ){	
      
      
      
      
      
            			process_msg($bd,$msg);
      
      
      
      
      
          			}
      
      
      
      
      
        		} 
      
      
      
      
      
      	}
      
      
      
      
      
      
        Sorry, stack_out_get returns a hash with all the resultset of de query, 10 records each like
        id|TXT VARCHAR(2048)|timestamp_a|timestamp_b|app_Code VARCHAR(3)|number (integer)

        TXT lenght it's alway about 250 char, but in a future version could be greater.
        First of all let me say that I dearly hope that the conditional in this while loop has a typographical error:
        while(($key, $msg) = each %$msg) { process_msg($bs,$msg); }
        I hope you mean:
        while(($key, $msg) = each %$record)
        If you don't mean this, then this might be some of your problem. Try renaming your hash value.

        You can also make this much easier to read by using a foreach loop (if you only want to handle the msg):

        foreach my $msg (values %$records) { process_msg($bd, $msg); }

        Anyway, I wanted to suggest that you look at Perl's profiling package. It can't exactly help you find out where all your memory is going, but it might help you track down where it's being lost. (Note that you should definately be using "my" for each of your variables to ensure that they don't hang around out of scope.)

        You can read about Perl's profiling package with perldoc Devel::DProf

        The shorts of it are to profile a script run the perl interpreter with the -d switch. So perl -d:DProf test.pl. when it's done, check the results by running dprofpp or dprofpp -T.

        I hope that helps. :)

        Does the program grow if you leave out that process_msg subroutine call?

        Also, use strict and my variables where possible, and don't make circular references like $a = \$b; $b = \$a;, or they'll never really get out of scope (they might go out of scope and be unreachable, but since they refer to eachother, they'll never go away)

Re: Perl memory Memory consumption
by mitd (Curate) on Nov 22, 2001 at 22:55 UTC
    Here is some reading they should be helpful. DBI can be tough on memory so check this article out. Also this article although it deals with mod_perl it has some good info on Perl memory usuage in general.

    Finally,If you haven't already done so, check out perldebguts debugging memory section.

    mitd-Made in the Dark
    'Interactive! Paper tape is interactive!
    If you don't believe me I can show you my paper cut scars!'

Re: Perl memory Memory consumption
by perrin (Chancellor) on Nov 22, 2001 at 22:37 UTC
    In general, Perl will choose the right malloc for your system. I played around with these setting a couple of years ago and never saw any real benefit in terms of memory savings.

    What's probably happening is that you have some data which isn't properly scoped so it's not getting cleaned up. If you can post some of your code, people here may be able to help. Make sure your are using strict and warnings to catch accidents.

    If you have really huge data structures that you have to process, you could look for a way to swap speed for memory consumption by storing parts of it on disk while you work on it. (Storable is good for this.) Obviously this doesn't work with an approach that requires one large structure.

Re: Perl memory Memory consumption
by fokat (Deacon) on Nov 23, 2001 at 02:29 UTC
    I have an application in production now (actually a DNS server) which answers in excess of 100 queries/sec, uses DBI to talk to its backend (DBD::Oracle) and its footprint is nowhere near that.

    I think you definitely have a memory leak. Please observe the pattern of memory usage. If it grows slowly, a leak is the most likely cause.

    As others said, if you post your code (or the relevant parts of it), probably a lot of help can result :)

    Good luck.