- Saved searches
- Use saved searches to filter your results more quickly
- License
- BitOne/php-meminfo
- Name already in use
- Sign In Required
- Launching GitHub Desktop
- Launching GitHub Desktop
- Launching Xcode
- Launching Visual Studio Code
- Latest commit
- Git stats
- Files
- README.md
- About
- Saved searches
- Use saved searches to filter your results more quickly
- gnomeby/php-memtest
- Name already in use
- Sign In Required
- Launching GitHub Desktop
- Launching GitHub Desktop
- Launching Xcode
- Launching Visual Studio Code
- Latest commit
- Git stats
- Files
- README.md
- About
- Testing Memory Allocation
- Code
- Output
Saved searches
Use saved searches to filter your results more quickly
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
PHP extension to get insight about memory usage
License
BitOne/php-meminfo
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Sign In Required
Please sign in to use Codespaces.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
README.md
PHP Meminfo is a PHP extension that gives you insights on the PHP memory content.
Its main goal is to help you understand memory leaks: by looking at data present in memory, you can better understand your application behaviour.
One of the main sources of inspiration for this tool is the Java jmap tool with the -histo option (see man jmap ).
For older versions of PHP, you can use the following releases:
- 5.6: PHP Meminfo v1.1
- 5.5: PHP Meminfo v1.0.5 (may work with PHP 5.3 and PHP 5.4 but not tested)
From the root of the extension directory:
$ phpize $ ./configure --enable-meminfo $ make $ make install
Add the following line to your php.ini :
Analyzers allow to analyze a memory dump (see below).
$ cd analyzer $ composer install
meminfo_dump(fopen('/tmp/my_dump_file.json', 'w'));
This function generates a dump of the PHP memory in a JSON format. This dump can be later analyzed by the provided analyzers.
This function takes a stream handle as a parameter. It allows you to specify a file (ex fopen(‘/tmp/file.txt’, ‘w’) , as well as to use standard output with the php://stdout stream.
Displaying a summary of items in memory
$ bin/analyzer summary dump-file> Arguments: dump-file PHP Meminfo Dump File in JSON format
$ bin/analyzer summary /tmp/my_dump_file.json +----------+-----------------+-----------------------------+ | Type | Instances Count | Cumulated Self Size (bytes) | +----------+-----------------+-----------------------------+ | string | 132 | 7079 | | MyClassA | 100 | 7200 | | array | 10 | 720 | | integer | 5 | 80 | | float | 2 | 32 | | null | 1 | 16 | +----------+-----------------+-----------------------------+
Displaying a list of objects with the largest number of children
$ bin/analyzer top-children [options] [--] dump-file> Arguments: dump-file PHP Meminfo Dump File in JSON format Options: -l, --limit[=LIMIT] limit [default: 5]
$ bin/analyzer top-children /tmp/my_dump_file.json +-----+----------------+----------+ | Num | Item ids | Children | +-----+----------------+----------+ | 1 | 0x7ffff4e22fe0 | 1000000 | | 2 | 0x7fffe780e5c8 | 11606 | | 3 | 0x7fffe9714ef0 | 11602 | | 4 | 0x7fffeab63ca0 | 3605 | | 5 | 0x7fffd3161400 | 2400 | +-----+----------------+----------+
Querying the memory dump to find specific objects
$ bin/analyzer query [options] [--] dump-file> Arguments: dump-file PHP Meminfo Dump File in JSON format Options: -f, --filters=FILTERS Filter on an attribute. Operators: =, ~. Example: class~User (multiple values allowed) -l, --limit=LIMIT Number of results limit (default 10). -v Increase the verbosity
$ bin/analyzer query -v -f "class=MyClassA" -f "is_root=0" /tmp/php_mem_dump.json +----------------+-------------------+------------------------------+ | Item ids | Item data | Children | +----------------+-------------------+------------------------------+ | 0x7f94a1877008 | Type: object | myObjectName: 0x7f94a185cca0 | | | Class: MyClassA | | | | Object Handle: 1 | | | | Size: 72 B | | | | Is root: No | | +----------------+-------------------+------------------------------+ | 0x7f94a1877028 | Type: object | myObjectName: 0x7f94a185cde0 | | | Class: MyClassA | | | | Object Handle: 2 | | | | Size: 72 B | | | | Is root: No | | +----------------+-------------------+------------------------------+ | 0x7f94a1877048 | Type: object | myObjectName: 0x7f94a185cf20 | | | Class: MyClassA | | .
Displaying the reference path
The reference path is the path between a specific item in memory (identified by its pointer address) and all the intermediary items up to the one item that is attached to a variable still alive in the program.
This path shows which items are responsible for the memory leak of the specific item provided.
$ bin/analyzer ref-path item-id> dump-file> Arguments: item-id Item Id in 0xaaaaaaaa format dump-file PHP Meminfo Dump File in JSON format Options: -v Increase the verbosity
$ bin/analyzer ref-path -v 0x7f94a1877068 /tmp/php_mem_dump.json Found 1 paths Path from 0x7f94a1856260 +--------------------+ | Id: 0x7f94a1877068 | | Type: object | | Class: MyClassA | | Object Handle: 4 | | Size: 72 B | | Is root: No | | Children count: 1 | +--------------------+ ^ | 3 | | +---------------------+ | Id: 0x7f94a185cb60 | | Type: array | | Size: 72 B | | Is root: No | | Children count: 100 | +---------------------+ ^ | second level | | +--------------------+ | Id: 0x7f94a185ca20 | | Type: array | | Size: 72 B | | Is root: No | | Children count: 1 | +--------------------+ ^ | first level | | +---------------------------+ | Id: 0x7f94a1856260 | | Type: array | | Size: 72 B | | Is root: Yes | | Execution Frame: GLOBAL> | | Symbol Name: myRootArray | | Children count: 1 | +---------------------------+
A workflow to find and understand memory leaks using PHP Meminfo
Other memory debugging tools for PHP
- XDebug (https://xdebug.org/) With the trace feature and the memory delta option (tool see XDebug documentation), you can trace function memory usage. You can use the provided script to get an aggregated view (TODO link)
- PHP Memprof (https://github.com/arnaud-lb/php-memory-profiler) Provides aggregated data about memory usage by functions. Far less resource intensive than a full trace from XDebug.
«A lot of memory usage is reported by the memory_usage entry, but the cumulative size of the items in the summary is far lower than the memory usage»
A lot of memory is used internally by the Zend Engine itself to compile PHP files, to run the virtual machine, to execute the garbage collector, etc. Another part of the memory is usually taken by PHP extensions themselves. And the remaining memory usage comes from the PHP data structures from your program.
In some cases, several hundred megabytes can be used internally by some PHP extensions. Examples are the PDO extension and MySQLi extension. By default, when executing a SQL query they will buffer all the results inside the PHP memory: http://php.net/manual/en/mysqlinfo.concepts.buffering.php
In case of very large number of results, this will consume a lot of memory, and this memory usage is not caused by the data you have in your objects or array manipulated by your program, but by the way the extension works.
This is only one example, but the same can happen with image manipulation extensions, that will use a lot of memory to transform images.
All the extensions are using the Zend Memory Manager, so that they will not exceed the maximum memory limit set for the PHP process. So their memory usage is included in the information provided by memory_get_usage() .
But PHP Meminfo is only able to get information on memory used by the data structure from the PHP program, not from the extensions themselves.
Hence the difference between those numbers, which can be quite big.
«Call to undefined function» when calling meminfo_dump
This means the extension is not enabled.
Check the PHP Info output and look for the MemInfo data.
To see the PHP Info output, just create a page calling the phpinfo(); function, and load it from your browser, or call php -i from the command line.
Why most tests are «skipped»?
While doing a make test , some tests will need JSON capabilities. But the compilation system generates a clean env by removing all configuration directives that load extensions. So if JSON capabilites are packaged as a separate extension (instead of being compiled directly in the PHP runtime), the tests will be skipped.
You may run them with the run-tests.php generated after the make test command, by providing the php executable:
$ TEST_PHP_EXECUTABLE=$(which php) $(which php) run-tests.php -d extension=$PWD/modules/meminfo.so
In this case your tests will run with your local PHP configuration, including the loading of the JSON extension.
Please note this is not required when working with PHP 8 as the JSON functions are now usually complied in PHP directly.
Thanks to Derick Rethans for his inspirational work on the essential XDebug. See http://www.xdebug.org/
About
PHP extension to get insight about memory usage
Saved searches
Use saved searches to filter your results more quickly
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
Test suite that meters consuming memory by PHP objects
gnomeby/php-memtest
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Sign In Required
Please sign in to use Codespaces.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
README.md
Test suite that meters consuming memory by PHP objects and other operators.
php run.include-test.php — test how includes consume memory
php run.testsuite-without-accelerator.php — a set of tests that measures consuming memory in different situations. PHP Accelerator will be ignored.
http://localhost/run.testsuite-with-accelerator.php — a set of tests that measures consuming memory in different situations. PHP Accelerator will be used.
About
Test suite that meters consuming memory by PHP objects
Testing Memory Allocation
This nice routine is for testing PHP’s memory limits by increasingly allocating 50 more megabytes at a time. Each pass is setting the memory limit with an ini_set, then attempting to use just right up to that (10 megs under). It will run fairly fast until you start paging. You might want to turn the 6000 (6 gigs) to something that will fit on your server. The idea is to run this under the context where you’re having problems allocating memory with your PHP script and it should help you figure out how much memory you can use before your script breaks.
Code
function tryMem($mbyte) < $bytes = 1048576; echo("\tAllocate Attempt MBs\n"); $dummy = str_repeat("0", $bytes*$mbyte); echo("Current Memory Use: " . memory_get_usage(true)/$bytes . ' MBs'); echo("\tPeak Memory Use: " . memory_get_peak_usage(true)/$bytes . ' MBs'); echo("\n"); > for($i=10;$i
Output
Memory limit set to: 10M Allocate Attempt 0 MBs
Current Memory Use: 0.25 MBs Peak Memory Use: 0.25 MBs
Memory limit set to: 110M Allocate Attempt 100 MBs
Current Memory Use: 100.5 MBs Peak Memory Use: 100.5 MBs
Memory limit set to: 210M Allocate Attempt 200 MBs
Current Memory Use: 200.5 MBs Peak Memory Use: 200.5 MBs
Memory limit set to: 310M Allocate Attempt 300 MBs
Current Memory Use: 300.5 MBs Peak Memory Use: 300.5 MBs
Memory limit set to: 410M Allocate Attempt 400 MBs
Current Memory Use: 400.5 MBs Peak Memory Use: 400.5 MBs
Memory limit set to: 510M Allocate Attempt 500 MBs
Current Memory Use: 500.5 MBs Peak Memory Use: 500.5 MBs
Memory limit set to: 610M Allocate Attempt 600 MBs
Current Memory Use: 600.5 MBs Peak Memory Use: 600.5 MBs
Memory limit set to: 710M Allocate Attempt 700 MBs
Current Memory Use: 700.5 MBs Peak Memory Use: 700.5 MBs
Memory limit set to: 810M Allocate Attempt 800 MBs
Current Memory Use: 800.5 MBs Peak Memory Use: 800.5 MBs
Memory limit set to: 910M Allocate Attempt 900 MBs
Current Memory Use: 900.5 MBs Peak Memory Use: 900.5 MBs
Memory limit set to: 1010M Allocate Attempt 1000 MBs