Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
Devel::MAT::UserGuide(User Contributed Perl DocumentatDevel::MAT::UserGuide(3)

NAME
       "Devel::MAT::UserGuide" - a users' introduction to "Devel::MAT"

OVERVIEW
       The "Devel::MAT"	ecosystem allows developers of perl programs to
       inspect and analyse memory-related problems such	as memory leaks,
       unexpected memory consumption, or odd state. This is an "offline"
       analysis	system,	in the sense that the analysis tools all run in	a
       different process, possibly at a	later time, than the perl process that
       is being	analysed.

       The basic workflow consists of two main stages: first a heap dump file
       is generated from the perl process being	debugged, at or	around the
       time that the problem becomes apparent, and secondly this file is
       loaded by an analysis tool in order to inspect the contents.

       These two stages	are described here separately. It is important to note
       that they don't have to be done at the same time, on the	same perl
       process,	or even	on the same sort of machine. It	is fully possible to
       capture the heap	from a process on, say,	a small	server,	then copy the
       file to a development workstation or laptop and analyse it there	at a
       later time. It is for this reason that the heap-dumping part,
       Devel::MAT::Dumper, is now separated into its own CPAN distribution.
       This means it can be installed on its own, without all the extra
       dependencies the	full set of analysis tools require.

CAPTURING THE HEAP
       To generate the heap dump file that captures the	contents of the	heap,
       the Devel::MAT::Dumper module is	used. Ultimately the "dump" function
       within it needs to be called, but usually one of	the module load
       options can be used on the perl commandline to achieve this without
       requiring the running code to be	modified.

       For example, the	"-dump_at_DIE" option means that a heap	dump will be
       written just before the process quits due to an uncaught	exception:

	 $ perl	-MDevel::MAT::Dumper=-dump_at_DIE program.pl

       At this point, the program will start up	and run	normally, but if it is
       about to	die, it	will first write a .pmat file capturing	the contents
       of the memory.

	 ...
	 Dumping to program.pl.pmat because of DIE
	 Can't call method "method" on an undefined value at program.pl	line 123.

       There are a variety of other options for	other situations, to suit
       other sorts of bugs and issues under investigation. For more options,
       see the documentation at	"IMPORT	OPTIONS" in Devel::MAT::Dumper.

ANALYSING THE HEAP
       Now that	we have	a .pmat	file, we can load it and start to inspect the
       contents. A lot of the smaller, simpler tools are built as plugins for
       the main	pmat command shell, so we can start by loading the heap	file
       there.

	 $ pmat	program.pl.pmat
	 Perl memory dumpfile from perl	5.24.1
	 Heap contains 15624 objects
	 pmat>

       In this shell a collection of commands is available to help analyse and
       inspect the contents of memory represented by this heap dump, which can
       be used in an interactive way, trying to	narrow down to find the	cause
       of the memory issue.

       It is hard in general to	describe exactly what sequence of analysis
       commands	will be	best to	find the problem, as the specifics of each
       individual case will call for different kinds of	analysis and require
       us to ask different questions of	the toolset.

       Ultimately there	is quite a variety of possible underlying causes of
       memory growth in	a Perl program;	a few possible causes could be:

       o A single large	SV such	as a hash or array containing millions of
	 items,	or a single string possibly gigabytes in length.

       o A large number	of SVs being created retained indefinitely, never
	 being reclaimed.

       o A large number	of temporary SVs being created,	but due	to internal
	 reference cycles their	memory is never	reclaimed despite them now
	 being unreachable.

       This list of course is quite incomplete - there are as many different
       variations of erroenous memory usage as there are possible programs to
       write.  Additionally, a lot of more interesting programs	often suffer
       multiple	overlapping issues at once. Nevertheless, this broad
       categorisation can help to describe some	overall	approaches to finding
       memory usage issues.

       A good first step to take in the	pmat shell to try to distinguish these
       cases is	to use the "largest" command. This command requires no
       additional arguments, and by default will print (in size	order),	the
       five largest individual SVs in the entire heap.

	 pmat> largest

       For more	information about the "largest"	command, see also "largest" in
       Devel::MAT::Tool::Sizes.

   One Large SV
       Sometimes you'll	find a single SV that far outweighs all	the others;
       for example:

	 pmat> largest
	 SCALAR(PV) at 0x6a47708: 1.6 GiB
	 SCALAR(PV) at 0x1a59488: 4.0 MiB
	 HASH(0) at 0xfb4770=strtab: 1.5 MiB
	 SCALAR(PV) at 0x71b6468: 707.3	KiB
	 SCALAR(PV) at 0x71be2f0: 609.6	KiB
	 others: 46.2 MiB

       In this output, we see that the topmost SV reported, at address
       0x6a47708 is much larger	than everything	else put together. In this
       case we have essentially	already	found the cause	of the memory usage
       growth, and we can proceed by identifying what this particular SV
       actually	is, by following the process in
       Devel::MAT::UserGuide::IdentifyingAnSV.

       For a brief overview, we	can just count the total number	of objects of
       various kinds in	the heap:

	 pmat> count
	   Kind	      Count (blessed)	     Bytes (blessed)
	   ARRAY	182	    0	  16.0 KiB
	   CODE		182	    0	  22.8 KiB
	   GLOB		325	    0	  48.2 KiB
	   ...

       We can inspect the callstack at the time	the heap dump was made:

	 pmat> callstack
	 program.pl line 152: &main::func => void
	   $_[0]: SCALAR(PV) at	0x55c2bdce2778 = "arguments"
	   $_[1]: SCALAR(PV) at	0x55c2bdce2868 = "go"
	   $_[2]: SCALAR(PV) at	0x55c2bdce26e8 = "here"
	 ...

COMMAND	HELP
       A list of the commands currently	available in the shell can be found by
       the "help" command:

	 pmat> help
	 callstack - Display the call stack
	 count	   - Count the various kinds of	SV
	 elems	   - List the elements of an ARRAY SV
	 ...

       For more	information about a particular command,	give its name as an
       argument	to the "help" command:

	 pmat> help sizes
	 sizes - Summarize object and byte counts across different SV types

	 SYNOPSIS:
	   sizes [OPTIONS...]

	 OPTIONS:
	   --owned     sum SVs by owned	size
	   --struct    sum SVs by structural size

       Also note that each command is implemented by a (correctly-cased)
       package under the "Devel::MAT::Tool" namespace. For example, the
       "count" tool is implemented by, and therefore more documentation	can be
       found in, the Devel::MAT::Tool::Count package.

   Specifying SVs
       Many commands operate on	a particular given SV. This can	be specified
       in several ways:

       o   A numerical address directly:

	      pmat> show 0x55a7e4e59f78
	      IO()=IO::File at 0x55a7e4e59f78 with refcount 1
	      ...

       o   A named root	SV (see	the "roots" command for	a list of them all):

	      pmat> show defstash
	      STASH(61)	at 0x55a7e4d69060=defstash with	refcount 2

       o   A named symbol from the symbol table. Note that subs	require	the
	   "&" sigil:

	     pmat> show	$warnings::VERSION
	     SCALAR(PV)	at 0x55a7e4d96550 with refcount	1
	     ...

	     pmat> show	&warnings::import
	     CODE(PP) at 0x55a7e4dc3458	with refcount 1
	     ...

AUTHOR
       Paul Evans <leonerd@leonerd.org.uk>

perl v5.32.1			  2021-02-28	      Devel::MAT::UserGuide(3)

NAME | OVERVIEW | CAPTURING THE HEAP | ANALYSING THE HEAP | COMMAND HELP | AUTHOR

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=Devel::MAT::UserGuide&sektion=3&manpath=FreeBSD+13.0-RELEASE+and+Ports>

home | help