Memory profiler for PHP. Helps finding memory leaks in PHP scripts.
Memory profiler for PHP. Helps finding memory leaks in PHP scripts.
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 and sys/queue.h.
On Debian-based distributions the dependencies can be installed with:
# Debian or Ubuntu:
apt install libjudy-devOn Alpine:
# Alpine
apk add judy-dev bsd-compat-headersOn MacOS:
# install libjudy dependency:
brew install traildb/judy/judyMake sure to install dependencies, and then:
pie install arnaud-lb/memprofNote If libjudy is installed in a non-standard path (not /usr or /usr/local), you need to specify it via the
--with-judy-diroption.Example on MacOS:
pecl install memprof --with-judy-dir=$(brew --prefix traildb/judy/judy)
Make sure to install dependencies, and then:
pecl install memprofNote If libjudy is installed in a non-standard path (not /usr or /usr/local), you need to specify it via the
JUDY_DEVenvironment variable.Example on MacOS:
JUDY_DIR=$(brew --prefix traildb/judy/judy) 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 installNote If libjudy is installed in a non-standard path (not /usr or /usr/local), you can specify it like this:
./configure --with-judy-dir=/opt/homebrew/Cellar/judy/1.0.5Arch Linux users may prefer to install the unofficial php-memprof [package][8]
with makepkg or their preferred AUR [helper][9]. If using yay, for example:
yay -S php-memprofℹ️ Please report any issues with this package on its AUR [page][8].
The extension can be loaded on the command line, just for one script:
php -dextension=memprof.so script.phpOr permanently, in php.ini:
extension=memprof.soThe extension has no overhead when not profiling, so it can be loaded by default on dev environments.
The simplest way to use memprof is to let it save the memory profile when the
program's memory limit is exceeded.
dump_on_limit modeProfiling in dump_on_limit mode is enabled at request startup when one
of these is true:
MEMPROF_PROFILE is equal to dump_on_limit$_GET["MEMPROF_PROFILE"] is equal to dump_on_limit$_POST["MEMPROF_PROFILE"] is equal to dump_on_limitFor command line scripts, we can set the environment variable:
MEMPROF_PROFILE=dump_on_limit php test.phpFor web scripts, we can set the $_GET variable:
curl http://127.0.0.1/test.php?MEMPROF_PROFILE=dump_on_limitOr the $_POST variable:
curl -d MEMPROF_PROFILE=dump_on_limit http://127.0.0.1/test.phpNote The
memprof_enabled_flags()function can be called to check whether profiling is currently enabled indump_on_limitmode.
In this mode, memprof will 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 /tmp
or 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 kcachegrind package ready to be installed.
For example, Ubuntu or Debian:
sudo apt install kcachegrindOther 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_PROFILE is non-empty$_GET["MEMPROF_PROFILE"] is non-empty$_POST["MEMPROF_PROFILE"] is non-emptyThe MEMPROF_PROFILE variable accepts a comma-separated list of flags.
Examples of valid MEMPROF_PROFILE values:
1: non-empty: profiling is enableddump_on_limit: profiling is enabled, will dump on memory limitnative: profiling is enabled, will profile native allocationsdump_on_limit,native: profiling is enabled, will profile native allocations, will dump on memory limitList of valid flags:
dump_on_limit: Will dump the profile in callgrind format in /tmp or
C:\Windows\Temp. The output directory can be changed with the
memprof.output_dir ini 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_PROFILE to 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.
The output file format is defined with the memprof.output_format ini setting. The options are:
callgrind (default)pprofReturns 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.
Example output
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
(
)
)
)
)
)
)
### memprof_version()
Returns the version of the extension as a string. The version can be compared with [version_compare()](https://php.net/version_compare).
## Troubleshooting
* The extensions may conflict with xdebug, blackfire, or other extensions. If that's the case for you, please report it.
## PHP versions
The current branch supports PHP 7.1 to PHP 8.
The php5 branch supports PHP 5.
## How it works
See [INTERNALS.md][7]
[1]: https://www.gnu.org/software/libc/manual/html_node/Hooks-for-Malloc.html#Hooks-for-Malloc
[2]: https://kcachegrind.github.io/html/Home.html
[3]: http://judy.sourceforge.net/index.html
[5]: https://github.com/gperftools/gperftools
[6]: https://www.google.com/search?q=qcachegrind
[7]: https://github.com/arnaud-lb/php-memory-profiler/blob/master/INTERNALS.md
[8]: https://aur.archlinux.org/packages/php-memprof/
[9]: https://wiki.archlinux.org/title/AUR_helpersNo open issues yet, or sync has not completed.