{"id":13560732,"url":"https://github.com/arnaud-lb/php-memory-profiler","last_synced_at":"2025-05-14T17:08:26.854Z","repository":{"id":5850474,"uuid":"7067090","full_name":"arnaud-lb/php-memory-profiler","owner":"arnaud-lb","description":"Memory profiler for PHP. Helps finding memory leaks in PHP scripts.","archived":false,"fork":false,"pushed_at":"2025-03-01T13:00:10.000Z","size":634,"stargazers_count":903,"open_issues_count":15,"forks_count":53,"subscribers_count":15,"default_branch":"v3","last_synced_at":"2025-04-09T11:04:59.185Z","etag":null,"topics":["memory-allocation","memory-leak","memory-profiler","memprof","php","php-memprof","profiler"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/arnaud-lb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2012-12-08T12:14:19.000Z","updated_at":"2025-04-07T12:43:02.000Z","dependencies_parsed_at":"2024-08-01T13:16:17.151Z","dependency_job_id":"6c0900e3-8658-462f-91bb-fdb9c108d541","html_url":"https://github.com/arnaud-lb/php-memory-profiler","commit_stats":{"total_commits":138,"total_committers":10,"mean_commits":13.8,"dds":"0.15217391304347827","last_synced_commit":"9fa6eae94b7f9a84b029f8b24731035856c65067"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arnaud-lb%2Fphp-memory-profiler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arnaud-lb%2Fphp-memory-profiler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arnaud-lb%2Fphp-memory-profiler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arnaud-lb%2Fphp-memory-profiler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arnaud-lb","download_url":"https://codeload.github.com/arnaud-lb/php-memory-profiler/tar.gz/refs/heads/v3","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254190396,"owners_count":22029632,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["memory-allocation","memory-leak","memory-profiler","memprof","php","php-memprof","profiler"],"created_at":"2024-08-01T13:00:49.056Z","updated_at":"2025-05-14T17:08:26.835Z","avatar_url":"https://github.com/arnaud-lb.png","language":"C","funding_links":[],"categories":["C","代码分析"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://i.imgur.com/NHLeua6.png\" alt=\"memprof logo\" width=\"330\" height=\"330\" /\u003e\n\u003c/p\u003e\n\n# memprof\n\n![Supported PHP versions: 7.1 ... 8.x](https://img.shields.io/badge/php-7.1%20...%208.x-blue.svg)\n\nphp-memprof is a fast and accurate memory profiling extension for PHP that can be used to find the cause of memory leaks.\n\n## Features\n\nThe 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.\n\n * Reports non-freed memory at arbitrary points in the program\n * Dumps profile in callgrind, pprof, or raw array formats\n * Can track memory allocated by PHP itself as well as native malloc\n\n## Install\n\n### Dependencies\n\nphp-memprof depends on libjudy and sys/queue.h.\n\nOn Debian-based distributions the dependencies can be installed with:\n\n    # Debian or Ubuntu:\n    apt install libjudy-dev\n\nOn Alpine:\n\n    # Alpine\n    apk add judy-dev bsd-compat-headers\n\nOn MacOS:\n\n    # install libjudy dependency:\n    brew install traildb/judy/judy\n\n### Installing with [PIE](https://github.com/php/pie)\n\nMake sure to install [dependencies](#dependencies), and then:\n\n    pie install arnaud-lb/memprof\n\n\u003e **Note** If libjudy is installed in a non-standard path (not /usr or /usr/local), you need to specify it via the `--with-judy-dir` option.\n\u003e \n\u003e Example on MacOS:\n\u003e ```\n\u003e pecl install memprof --with-judy-dir=$(brew --prefix traildb/judy/judy)\n\u003e ```\n\n### Installing with PECL\n\nMake sure to install [dependencies](#dependencies), and then:\n\n    pecl install memprof\n\n\u003e **Note** If libjudy is installed in a non-standard path (not /usr or /usr/local), you need to specify it via the `JUDY_DEV` environment variable.\n\u003e \n\u003e Example on MacOS:\n\u003e ```\n\u003e JUDY_DIR=$(brew --prefix traildb/judy/judy) pecl install memprof\n\u003e ```\n\n### Installing manually\n\nMake sure to install [dependencies](#dependencies), and then:\n\nDownload the source and run the following commands in the source directory:\n\n    phpize\n    ./configure\n    make\n    make install\n\n\u003e **Note** If libjudy is installed in a non-standard path (not /usr or /usr/local), you can specify it like this:\n\n    ./configure --with-judy-dir=/opt/homebrew/Cellar/judy/1.0.5\n\n### Installing on Arch Linux\n\nArch Linux users may prefer to install the unofficial php-memprof [package][8]\nwith `makepkg` or their preferred AUR [helper][9]. If using `yay`, for example:\n\n    yay -S php-memprof\n\n\u003e ℹ️ Please report any issues with this package on its AUR [page][8].\n\n## Loading the extension\n\nThe extension can be loaded on the command line, just for one script:\n\n    php -dextension=memprof.so script.php\n\nOr permanently, in php.ini:\n\n    extension=memprof.so\n\nThe extension has no overhead when not profiling, so it can be loaded by default on dev environments.\n\n## Usage example\n\nThe simplest way to use `memprof` is to let it save the memory profile when the\nprogram's memory limit is exceeded.\n\n### Step 1: Enable profiling in `dump_on_limit` mode\n\nProfiling in `dump_on_limit` mode is enabled at request startup when one\nof these is true:\n\n * The environment variable `MEMPROF_PROFILE` is equal to `dump_on_limit`\n * `$_GET[\"MEMPROF_PROFILE\"]` is equal to `dump_on_limit`\n * `$_POST[\"MEMPROF_PROFILE\"]` is equal to `dump_on_limit`\n\nFor command line scripts, we can set the environment variable:\n\n```\nMEMPROF_PROFILE=dump_on_limit php test.php\n```\n\nFor web scripts, we can set the `$_GET` variable:\n\n```\ncurl http://127.0.0.1/test.php?MEMPROF_PROFILE=dump_on_limit\n```\n\nOr the `$_POST` variable:\n\n```\ncurl -d MEMPROF_PROFILE=dump_on_limit http://127.0.0.1/test.php\n```\n\n\u003e **Note** The `memprof_enabled_flags()` function can be called to\n\u003e check whether profiling is currently enabled in `dump_on_limit` mode.\n\n### Step 2: Dumping the profile\n\nIn this mode, `memprof` will automatically save the profile if the program\nexceeds the memory limit (when PHP triggers an error like `Fatal error: Allowed\nmemory size of 15728640 bytes exhausted (tried to allocate 1024 bytes)` error).\n\nBy default, the profile is saved in a file named `memprof.callgrind.*` in `/tmp`\nor `C:\\Windows\\Temp`.\n\n### Step 3: Visualizing the profile\n\nThe 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.\n\n#### Install Kcachegrind on Linux\n\nMost distributions have a `kcachegrind` package ready to be installed.\n\nFor example, Ubuntu or Debian:\n\n```\nsudo apt install kcachegrind\n```\n\nOther distributions most likely have a package ready to be installed as well.\n\n#### Install Qcachegrind on MacOS\n\nUse Homebrew: https://formulae.brew.sh/formula/qcachegrind\n\n#### Install Qcachegrind on Windows\n\nDownload it from https://sourceforge.net/projects/qcachegrindwin/\n\n## Advanced usage\n\n### Profile trigger\n\nProfiling is enabled at request startup when one of these is true:\n\n * The environment variable `MEMPROF_PROFILE` is non-empty\n * `$_GET[\"MEMPROF_PROFILE\"]` is non-empty\n * `$_POST[\"MEMPROF_PROFILE\"]` is non-empty\n\n### Profile flags\n\nThe `MEMPROF_PROFILE` variable accepts a comma-separated list of flags.\n\nExamples of valid `MEMPROF_PROFILE` values:\n\n * `1`: non-empty: profiling is enabled\n * `dump_on_limit`: profiling is enabled, will dump on memory limit\n * `native`: profiling is enabled, will profile native allocations\n * `dump_on_limit,native`: profiling is enabled, will profile native allocations, will dump on memory limit\n\nList of valid flags:\n\n * `dump_on_limit`: Will dump the profile in callgrind format in `/tmp` or\n   `C:\\Windows\\Temp`. The output directory can be changed with the\n   `memprof.output_dir` ini setting.\n * `native`: Will profile native `malloc()` allocations, not only PHP's (This is\n   not thread safe, see bellow).\n\n### Profiling native allocations\n\nMemprof doesn't track native allocations by default, but this can be enabled\nby setting `MEMPROF_PROFILE` to `native`.\n\nNative allocations are the allocations made outside of PHP's own memory\nallocator. Typically, external libraries such as libxml2 (used in the DOM\nextension) make native allocations. PHP can also make native allocations for\npersistent resources.\n\nEnabling native allocation tracking will profile these allocations in addition\nto PHP's own allocations.\n\nNote that when native tracking is enabled, the program will crash if a native\nlibrary uses threads, because the underlying hooks are not thread safe.\n\n### Output format\n\nThe output file format is defined with the `memprof.output_format` ini setting. The options are:\n- `callgrind` (default)\n- `pprof`\n\n## Functions documentation\n\n### memprof_enabled()\n\nReturns whether memory profiling is currently enabled (see above).\n\n### memprof_enabled_flags()\n\nReturns whether memory profiling and which profiling features are enabled (see\nabove).\n\n### memprof_dump_callgrind(resource $stream)\n\nDumps the current profile in callgrind format. The result can be visualized with tools such as\n[KCacheGrind](#install-kcachegrind-on-linux) or [QCacheGrind](#install-qcachegrind-on-macos).\n\n``` php\n\u003c?php\nmemprof_dump_callgrind(fopen(\"output\", \"w\"));\n```\n\nHere is a QcacheGrind screenshot:\n\n![QCacheGrind screenshot](https://raw.githubusercontent.com/arnaud-lb/php-memory-profiler/v2/assets/qcachegrind.png)\n\n### memprof_dump_pprof(resource $stream)\n\nDumps the current profile in pprof format.\n\n``` php\n\u003c?php\nmemprof_dump_pprof(fopen(\"profile.heap\", \"w\"));\n```\n\nThe file can be visualized with [google-perftools][5]'s ``pprof`` tool. (See bellow for installation instructions.) \n\nDisplay annotated call-graph in web browser or in ``gv``:\n\n```\n$ pprof --web profile.heap\n$ # or:\n$ pprof --gv profile.heap\n```\n\n![pprof call-graph screenshot](https://i.stack.imgur.com/EAnGC.png)\n\nOutput one line per function, sorted by own memory usage:\n\n```\n$ pprof --text profile.heap\n```\n\n#### ``pprof`` installation instructions:\n\nUbuntu: `apt install google-perftools`. On Ubuntu the tool is named ``google-pprof``, so you need to replace ``pprof`` with ``google-pprof`` in the examples above.\n\n### memprof_dump_array()\n\nReturns an array representing the current profile.\n\n``` php\n\u003c?php\n$dump = memprof_dump_array();\n```\n\nThe array exposes the following information:\n\n * Inclusive and exclusive memory leaked by functions (counting only the memory\n   that has is still not freed when memprof_dump_array is called)\n * Inclusive and exclusive blocks count of functions (number of allocations;\n   counting only the blocks that are still not freed when memprof_dump_array is\n   called)\n * The data is presented in call stacks. This way, if a function is called from\n   multiple places, it is possible to see which call path caused it to leak the\n   most memory\n\n\u003cdetails\u003e\n\u003csummary\u003eExample output\u003c/summary\u003e\n\n    Array\n    (\n      [memory_size] =\u003e 11578\n      [blocks_count] =\u003e 236\n      [memory_size_inclusive] =\u003e 10497691\n      [blocks_count_inclusive] =\u003e 244\n      [calls] =\u003e 1\n      [called_functions] =\u003e Array\n        (\n          [main] =\u003e Array\n            (\n              [memory_size] =\u003e 288\n              [blocks_count] =\u003e 3\n              [memory_size_inclusive] =\u003e 10486113\n              [blocks_count_inclusive] =\u003e 8\n              [calls] =\u003e 1\n              [called_functions] =\u003e Array\n                (\n                  [a] =\u003e Array\n                    (\n                      [memory_size] =\u003e 4\n                      [blocks_count] =\u003e 1\n                      [memory_size_inclusive] =\u003e 10485825\n                      [blocks_count_inclusive] =\u003e 5\n                      [calls] =\u003e 1\n                      [called_functions] =\u003e Array\n                        (\n                          [b] =\u003e Array\n                            (\n                              [memory_size] =\u003e 10485821\n                              [blocks_count] =\u003e 4\n                              [memory_size_inclusive] =\u003e 10485821\n                              [blocks_count_inclusive] =\u003e 4\n                              [calls] =\u003e 1\n                              [called_functions] =\u003e Array\n                                (\n                                  [str_repeat] =\u003e Array\n                                    (\n                                      [memory_size] =\u003e 0\n                                      [blocks_count] =\u003e 0\n                                      [memory_size_inclusive] =\u003e 0\n                                      [blocks_count_inclusive] =\u003e 0\n                                      [calls] =\u003e 1\n                                      [called_functions] =\u003e Array\n                                        (\n                                        )\n                                    )\n                                )\n                            )\n                        )\n                    )\n                  [memprof_dump_array] =\u003e Array\n                    (\n                      [memory_size] =\u003e 0\n                      [blocks_count] =\u003e 0\n                      [memory_size_inclusive] =\u003e 0\n                      [blocks_count_inclusive] =\u003e 0\n                      [calls] =\u003e 1\n                      [called_functions] =\u003e Array\n                        (\n                        )\n                    )\n                )\n            )\n        )\n    )\n\u003c/details\u003e\n\n### memprof_version()\n\nReturns the version of the extension as a string. The version can be compared with [version_compare()](https://php.net/version_compare).\n\n## Troubleshooting\n\n * The extensions may conflict with xdebug, blackfire, or other extensions. If that's the case for you, please report it.\n\n## PHP versions\n\nThe current branch supports PHP 7.1 to PHP 8.\n\nThe php5 branch supports PHP 5.\n\n## How it works\n\nSee [INTERNALS.md][7]\n\n[1]: https://www.gnu.org/software/libc/manual/html_node/Hooks-for-Malloc.html#Hooks-for-Malloc\n[2]: https://kcachegrind.github.io/html/Home.html\n[3]: http://judy.sourceforge.net/index.html\n[5]: https://github.com/gperftools/gperftools\n[6]: https://www.google.com/search?q=qcachegrind\n[7]: https://github.com/arnaud-lb/php-memory-profiler/blob/master/INTERNALS.md\n[8]: https://aur.archlinux.org/packages/php-memprof/\n[9]: https://wiki.archlinux.org/title/AUR_helpers\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farnaud-lb%2Fphp-memory-profiler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farnaud-lb%2Fphp-memory-profiler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farnaud-lb%2Fphp-memory-profiler/lists"}