Skip to content

Commit afcad6f

Browse files
committed
Support auto-dumping profile on memory exhaustion
1 parent 93daa73 commit afcad6f

File tree

7 files changed

+426
-126
lines changed

7 files changed

+426
-126
lines changed

README.md

Lines changed: 60 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -51,32 +51,51 @@ Or permanently, in php.ini:
5151

5252
The extension has no overhead when not profiling, so it can be loaded by default on dev environments.
5353

54-
## Usage
54+
## Usage example
5555

56-
Using the extension is done in three steps:
56+
The simplest way to use `memprof` is to let it save the memory profile when the
57+
program's memory limit is exceeded.
5758

58-
### 1. Enabling profile
59+
### Step 1: Enable profiling in `dump_on_limit` mode
5960

60-
Profiling is enabled at request startup when one of these is true:
61+
Profiling in `dump_on_limit` mode is enabled at request startup when one
62+
of these is true:
6163

62-
* The environment variable `MEMPROF_PROFILE` is non-empty
63-
* `$_GET["MEMPROF_PROFILE"]` is non-empty
64-
* `$_POST["MEMPROF_PROFILE"]` is non-empty
64+
* The environment variable `MEMPROF_PROFILE` is equal to `dump_on_limit`
65+
* `$_GET["MEMPROF_PROFILE"]` is equal to `dump_on_limit`
66+
* `$_POST["MEMPROF_PROFILE"]` is equal to `dump_on_limit`
67+
68+
For command line scripts, we can set the environment variable:
69+
70+
```
71+
MEMPROF_PROFILE=dump_on_limit php test.php
72+
```
73+
74+
For web scripts, we can set the `$_GET` variable:
75+
76+
```
77+
curl http://127.0.0.1/test.php?MEMPROF_PROFILE=dump_on_limit
78+
```
79+
80+
Or the `$_POST` variable:
81+
82+
```
83+
curl -d MEMPROF_PROFILE=dump_on_limit http://127.0.0.1/test.php
84+
```
6585

66-
The `memprof_enabled()` function can be called to check whether profiling is
67-
currently enabled.
86+
> :information_source: The `memprof_enabled_flags()` function can be called to
87+
> check whether profiling is currently enabled in `dump_on_limit` mode.
6888
69-
### 2. Dumping the profile
89+
### Step 2: Dumping the profile
7090

71-
When profiling is enabled, and once the program has reached a large memory usage,
72-
call ``memprof_dump_callgrind()`` or one it its variants to save the full
73-
profiling information to a file.
91+
In this mode, `memprof` will automatically save the profile if the program
92+
exceeds the memory limit (when PHP triggers an error like `Fatal error: Allowed
93+
memory size of 15728640 bytes exhausted (tried to allocate 1024 bytes)` error).
7494

75-
* Calling the function multiple times is not necessary
76-
* Waiting for a high memory usage before saving the profile makes it easier to
77-
find a leak
95+
By default, the profile is saved in a file named `memprof.callgrind.*` in `/tmp`
96+
or `C:\Windows\Temp`.
7897

79-
### 3. Visualizing the profile
98+
### Step 3: Visualizing the profile
8099

81100
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.
82101

@@ -100,35 +119,34 @@ Use Homebrew: https://formulae.brew.sh/formula/qcachegrind
100119

101120
Download it from https://sourceforge.net/projects/qcachegrindwin/
102121

103-
### Usage example
122+
## Advanced usage
104123

105-
```
106-
<?php // test.php
124+
### Profile trigger
107125

108-
do_some_work();
126+
Profiling is enabled at request startup when one of these is true:
109127

110-
if (function_exists('memprof_enabled') && memprof_enabled()) {
111-
memprof_dump_callgrind(fopen("/tmp/callgrind.out", "w"));
112-
}
113-
```
128+
* The environment variable `MEMPROF_PROFILE` is non-empty
129+
* `$_GET["MEMPROF_PROFILE"]` is non-empty
130+
* `$_POST["MEMPROF_PROFILE"]` is non-empty
114131

115-
When ran on the command line, profiling can be enabled by setting the `MEMPROF_PROFILE` environment variable:
132+
### Profile flags
116133

117-
```
118-
MEMPROF_PROFILE=1 php test.php
119-
```
134+
The `MEMPROF_PROFILE` variable accepts a comma-separated list of flags.
120135

121-
When ran in a web context, profiling can be enabled by setting the `MEMPROF_PROFILE` query string parameter or POST field:
136+
Examples of valid `MEMPROF_PROFILE` values:
122137

123-
```
124-
curl http://127.0.0.1/test.php?MEMPROF_PROFILE=1
125-
```
138+
* `1`: non-empty: profiling is enabled
139+
* `dump_on_limit`: profiling is enabled, will dump on memory limit
140+
* `native`: profiling is enabled, will profile native allocations
141+
* `dump_on_limit,native`: profiling is enabled, will profile native allocations, will dump on memory limit
126142

127-
Setting a POST field works as well:
143+
List of valid flags:
128144

129-
```
130-
curl -d MEMPROF_PROFILE=1 http://127.0.0.1/test.php
131-
```
145+
* `dump_on_limit`: Will dump the profile in callgrind format in `/tmp` or
146+
`C:\Windows\Temp`. The output directory can be changed with the
147+
`memprof.output_dir` ini setting.
148+
* `native`: Will profile native `malloc()` allocations, not only PHP's (This is
149+
not thread safe, see bellow).
132150

133151
### Profiling native allocations
134152

@@ -154,7 +172,8 @@ Returns whether memory profiling is currently enabled (see above).
154172

155173
### memprof_enabled_flags()
156174

157-
Returns whether memory profiling and native profiling are enabled (see above).
175+
Returns whether memory profiling and which profiling features are enabled (see
176+
above).
158177

159178
### memprof_dump_callgrind(resource $stream)
160179

@@ -217,7 +236,8 @@ The array exposes the following information:
217236
multiple places, it is possible to see which call path caused it to leak the
218237
most memory
219238

220-
Example output:
239+
<details>
240+
<summary>Example output</summary>
221241

222242
Array
223243
(
@@ -285,6 +305,7 @@ Example output:
285305
)
286306
)
287307
)
308+
</details>
288309

289310
## Troubleshooting
290311

0 commit comments

Comments
 (0)