Memory leak profiler for PHP
php-memprof is a fast and accurate memory profiling extension for PHP that can be used to find the cause of memory leaks.
The extension tracks the allocation and release of memory blocks to report the amount of memory leaked by every function, method, or file in a program.
php-memprof depends on libjudy. On Debian or Ubuntu, the dependency can be installed with:
# install libjudy dependency: apt install libjudy-dev
Make sure to install dependencies, and then:
pecl install memprof
Make sure to install dependencies, and then:
Download the source and run the following commands in the source directory:
phpize ./configure make make install
The extension can be loaded on the command line, just for one script:
php -dextension=memprof.so script.php
Or permanently, in php.ini:
extension=memprof.so
The extension has no overhead when not profiling, so it can be loaded by default on dev environments.
The simplest way to use
memprofis to let it save the memory profile when the program's memory limit is exceeded.
dump_on_limitmode
Profiling in
dump_on_limitmode is enabled at request startup when one of these is true:
MEMPROF_PROFILEis equal to
dump_on_limit
$_GET["MEMPROF_PROFILE"]is equal to
dump_on_limit
$_POST["MEMPROF_PROFILE"]is equal to
dump_on_limit
For command line scripts, we can set the environment variable:
MEMPROF_PROFILE=dump_on_limit php test.php
For web scripts, we can set the
$_GETvariable:
curl http://127.0.0.1/test.php?MEMPROF_PROFILE=dump_on_limit
Or the
$_POSTvariable:
curl -d MEMPROF_PROFILE=dump_on_limit http://127.0.0.1/test.php
:informationsource: The `memprofenabledflags()
function can be called to check whether profiling is currently enabled indumpon_limit` mode.
In this mode,
memprofwill automatically save the profile if the program exceeds the memory limit (when PHP triggers an error like
Fatal error: Allowed memory size of 15728640 bytes exhausted (tried to allocate 1024 bytes)error).
By default, the profile is saved in a file named
memprof.callgrind.*in
/tmpor
C:\Windows\Temp.
The recommended way to visualize the result is to use Kcachegrind (on Linux) or Qcachegrind (on MacOS, Windows). Google Perftools are also supported. See the documentation of
memprof_dump_callgrind()and variants.
Most distributions have a
kcachegrindpackage ready to be installed.
For example, Ubuntu or Debian:
sudo apt install kcachegrind
Other distributions most likely have a package ready to be installed as well.
Use Homebrew: https://formulae.brew.sh/formula/qcachegrind
Download it from https://sourceforge.net/projects/qcachegrindwin/
Profiling is enabled at request startup when one of these is true:
MEMPROF_PROFILEis non-empty
$_GET["MEMPROF_PROFILE"]is non-empty
$_POST["MEMPROF_PROFILE"]is non-empty
The
MEMPROF_PROFILEvariable accepts a comma-separated list of flags.
Examples of valid
MEMPROF_PROFILEvalues:
1: non-empty: profiling is enabled
dump_on_limit: profiling is enabled, will dump on memory limit
native: profiling is enabled, will profile native allocations
dump_on_limit,native: profiling is enabled, will profile native allocations, will dump on memory limit
List of valid flags:
dump_on_limit: Will dump the profile in callgrind format in
/tmpor
C:\Windows\Temp. The output directory can be changed with the
memprof.output_dirini setting.
native: Will profile native
malloc()allocations, not only PHP's (This is not thread safe, see bellow).
Memprof doesn't track native allocations by default, but this can be enabled by setting
MEMPROF_PROFILEto
native.
Native allocations are the allocations made outside of PHP's own memory allocator. Typically, external libraries such as libxml2 (used in the DOM extension) make native allocations. PHP can also make native allocations for persistent resources.
Enabling native allocation tracking will profile these allocations in addition to PHP's own allocations.
Note that when native tracking is enabled, the program will crash if a native library uses threads, because the underlying hooks are not thread safe.
Returns whether memory profiling is currently enabled (see above).
Returns whether memory profiling and which profiling features are enabled (see above).
Dumps the current profile in callgrind format. The result can be visualized with tools such as KCacheGrind or QCacheGrind.
Here is a QcacheGrind screenshot:
memprofdumppprof(resource $stream)
Dumps the current profile in pprof format.
The file can be visualized with google-perftools's
pproftool.Display annotated call-graph in web browser or in
gv:$ pprof --web profile.heap $ # or: $ pprof --gv profile.heap
Output one line per function, sorted by own memory usage:
$ pprof --text profile.heapmemprofdumparray()
Returns an array representing the current profile.
The array exposes the following information:
Array
(
[memory_size] => 11578
[blocks_count] => 236
[memory_size_inclusive] => 10497691
[blocks_count_inclusive] => 244
[calls] => 1
[called_functions] => Array
(
[main] => Array
(
[memory_size] => 288
[blocks_count] => 3
[memory_size_inclusive] => 10486113
[blocks_count_inclusive] => 8
[calls] => 1
[called_functions] => Array
(
[a] => Array
(
[memory_size] => 4
[blocks_count] => 1
[memory_size_inclusive] => 10485825
[blocks_count_inclusive] => 5
[calls] => 1
[called_functions] => Array
(
[b] => Array
(
[memory_size] => 10485821
[blocks_count] => 4
[memory_size_inclusive] => 10485821
[blocks_count_inclusive] => 4
[calls] => 1
[called_functions] => Array
(
[str_repeat] => Array
(
[memory_size] => 0
[blocks_count] => 0
[memory_size_inclusive] => 0
[blocks_count_inclusive] => 0
[calls] => 1
[called_functions] => Array
(
)
)
)
)
)
)
[memprof_dump_array] => Array
(
[memory_size] => 0
[blocks_count] => 0
[memory_size_inclusive] => 0
[blocks_count_inclusive] => 0
[calls] => 1
[called_functions] => Array
(
)
)
)
)
)
)
The current branch supports PHP 7.1 to PHP 8.
The php5 branch supports PHP 5.
See INTERNALS.md