The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Devel::MemoryTrace::Light - Print a message when your program grows in memory

VERSION

version 0.09

SYNOPSIS

  perl -d:MemoryTrace::Light Program

DESCRIPTION

Prints out a message when your program grows in memory containing the pid, package, file, line, and number of bytes (resident set size) your program increased. For example, if your program looked like this:

  #!/usr/bin/perl

  use strict;
  use warnings;

  my @arr;
  $arr[4096] = 'hello';

Then the output will look like:

  >> 324 init, 0 (0) used 8192 bytes
  >> 324 main, ex.pl (7) used 20480 bytes

MEMORYTRACE_LIGHT ENVIRONMENT VARIABLE

The MEMORYTRACE_LIGHT environment variable may be used to control some of the behaviors of Devel::MemoryTrace::Light. The format is key=value, and multiple values may be set at one time using the : separator. For example:

  export MEMORYTRACE_LIGHT=start=no:provider=MyClass

provider=...

Forces Devel::MemoryTrace::Light to use whatever class is passed in to determine memory usage.

The provider class must define a get_mem() method which should return the current process' memory size. The built in modules return the resident set size, but a custom provider could use virtual, swap, or whatever it wants, as long as it returns the same type of information consistently.

The provider class should also define a forked() method which will be called if Devel::MemoryTrace::Light detects that the process has forked. This method should do any re-initialization necessary for the provider class to accurately report memory for the new forked process.

The provider setting may also be used to force Devel::MemoryTrace::Light to prefer one of the built-in providers over another if more than one is installed.

start=...

Modify when tracing happens:

  start=begin - trace compilation of the program and beyond
  start=no    - disable tracing until C<DB::enable_trace()> is called

By default, tracing doesn't happen until the beginning of the INIT phase, after compilation. To see where memory growth is happening inside of use statements, use start=begin.

RUN-TIME CONTROL OF TRACING

A limited set of functionality is provided for run-time control of tracing.

DB::disable_trace()

DB::enable_trace()

You can control when tracing happens by using DB::enable_trace() and DB::disable_trace. This works well coupled with the start=no setting in the MEMORYTRACE_LIGHT environment variable described above.

DB::set_callback(\&somefunc)

If you would like to override the default behavior of printing to STDOUT whenever the program size increases, you may provide your own callback method.

This causes \&somefunc to be called whenever the debugger detects an increase in memory size. \&somefunc should accept 4 arguments:

  • $pkg

  • $file

  • $line

  • $bytes

DB::restore_callback()

Restores the default callback.

OS SUPPORT

Currently works on FreeBSD, Linux, and anywhere else GTop is supported.

On FreeBSD, installing this module will install BSD::Process unless GTop is already installed. BSD::Process will be preferred if both modules are on the system.

CAVEATS

  • Misleading results

    This module only identifies lines in a program that the resident set size increased at. This does not mean, however, that if you have a memory leak and you see bizarre lines increasing in size that they must be the problem. Often times, that's not the case. Consider the following example:

      #!/usr/bin/perl
    
      use strict;
      use warnings;
    
      my @cache;
    
      for (1..100_000) {
              nothing();
              use_mem();
      }
    
      sub nothing {
              my @arr = 5;
      }
    
      sub use_mem {
              push @cache, 1;
      }

    If you run the above code under Devel::MemoryTrace::Light, nothing() will be reported as using the most memory. In reality though, use_mem() is caching data and is the real cause of the memory consumption, but nothing() causes more actual memory growth as it tries to create a new array and assign a value to its first element.

    This is because after use_mem() returns and @arr goes out of scope, the memory allocated to @arr is potentially freed by the garbage collector, allowing use_mem() to use it without having to allocate more.

    Comment push @cache, 1; out in the program above and no memory growth should be reported.

  • Incorrect results

    It is possible for Devel::MemoryTrace::Light internals to cause memory usage and incorrect reports of growth, but it tries very hard to prevent this.

BUGS

Please report any bugs (or feature requests) through http://rt.cpan.org/.

AUTHOR

Matthew Horsfall (alh) - <WolfSage@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2011 by Matthew Horsfall.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.