in reply to Re^2: memory leak
in thread memory leak

Hmmm. Looking around though I think the problem may be how your version of perl is compiled (you need the debugging flags set).

There are other threads where people have similar issues

  • understanding devel::leak
  • Making Devel::Leak useful
  • also there is some good advice in Re: Memory Leak
  • HTH

    Just a something something...

    Replies are listed 'Best First'.
    Re^4: memory leak
    by bob_dobalina (Sexton) on Aug 26, 2009 at 20:08 UTC
      i think i found the issue;

      let's say getObjects opened and closed a db connection every call to get its data, using Win32::ODBC. This appears to be causing the memory to grow. here is an example:
      use Win32::ODBC; my @objects = (); my $i = 0; while($i < 20000000) { @objects = getObjects(); # do something $i += 100; } sub getObjects { my @objects = (); my $object = undef; my $db = undef; my $i = 0; $db = new Win32::ODBC("DSN=dsnname;UID=username;PWD=pw%") || die; for($i=0; $i<100; $i++) { #$object = new Obj("name_$i", $i); $objects[$i] = $object } if($db) { $db->Close(); } return @objects; }
      I tried adding $db = undef; with no luck. does $db not get re-used every call??

        I don't have any experience with Win32::ODBC, but looking at the release notes, $db shouldn't be the problem, as it is only storing the connection, not the data, and it falls out of scope at the end of the scope anyway, so it should be garbage collected and returned to the pool anyway.

        Are you sure that $db is being closed every time? Your script will die if the connection is not made, so there is no need for the if ($db){...} loop.

        I would also get rid of the global variable @objects and put the definition inside the while($i < 20000000) loop. This way you know that the array and it's contents are definitely out of scope with each iteration of the while loop.

        Perl garbage collection is refernce count based, (as i am sure everyone has already said), so if your memory really does continue to grow even though you have tightened the scoping, and are sure your new Obj("name_$i", $i) has not circularities, then my suspiscion would be that the ODBC memory is not being freed to the memory pool allocated to perl, but even this shouldn't be an issue because you are not making new DBs or adding to the DB right?

        One last thought, just to make sure your objects are being destroyed, you could add some debugging code along the lines of :

        use Win32::ODBC; use warnings; use strict; my $i = 0; while($i < 20000000) { print "***NEW ITERATION \$i = $i\n"; my @objects = getObjects(); # do something $i += 100; } sub getObjects { my @objects = (); my $object = undef; my $db = undef; my $i = 0; $db = new Win32::ODBC("DSN=dsnname;UID=username;PWD=pw%") || die " +Failed to establish connection\n"; for($i=0; $i<100; $i++) { #$object = new Obj("name_$i", $i); $objects[$i] = $object; print "Object ".( $object->to_string() )." created.\n"; } $db->Close(); return \@objects; } ################# IN Obj class definition ########### sub DESTROY{ my $self = shift; print "".( $self->to_string() )." biting the dust.\n"; }

        This way you should be able to be really sure that all Obj objects are being destroyed each iteration.

        Hope this helps, but i am not sure! Good luck!

        Just a something something...