Skip to content

Commit fecfcae

Browse files
authored
Merge pull request #45 from BitOne/php7
PHP7 Compatibility
2 parents 50ef567 + c8d6e55 commit fecfcae

37 files changed

+1226
-839
lines changed

.travis.yml

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
sudo: false
2+
3+
language: php
4+
5+
php:
6+
- 5.4
7+
- 5.5
8+
- 5.6
9+
- 7.0
10+
- 7.1
11+
- 7.2
12+
- nightly
13+
14+
matrix:
15+
allow_failures:
16+
- php: nightly
17+
18+
before_script:
19+
- phpenv config-rm xdebug.ini
20+
21+
script:
22+
- cd php$(echo $TRAVIS_PHP_VERSION | cut -b 1)/
23+
- phpize
24+
- configure
25+
- make
26+
- make test
27+
28+
after_script:
29+
- ./.travis.scripts/show-errors.sh

README.md

+45-124
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,24 @@ One of the main source of inspiration for this tool is the Java jmap tool with t
88

99
Compatibility
1010
-------------
11-
Compiled and tested on:
12-
13-
- PHP 5.4.4 (Debian 7)
14-
- PHP 5.5.8 (Ubuntu 12.04 LTS)
15-
- PHP 5.5.20 (CentOS 7)
16-
- PHP 5.6.17 (Debian 8)
11+
PHP 5.6 and PHP 7.1 (may work on PHP 7.0 and 7.2, but not tested yet).
1712

1813
Compilation instructions
1914
------------------------
2015
You will need the `phpize` command. It can be installed on a Debian based system by:
2116
```bash
2217
$ apt-get install php5-dev
2318
```
19+
for PHP 5, or
20+
```bash
21+
$ apt-get install php7.1-dev
22+
```
23+
for PHP 7.1 when using the Ondrej repository from sury.org.
2424

2525
Once you have this command, follow this steps:
2626

2727
## Compilation
28-
From the root of the `extension/` directory:
28+
From the root of the `extension/php5` for PHP 5 or `extension/php7` for PHP 7 directory:
2929

3030
```bash
3131
$ phpize
@@ -47,61 +47,57 @@ Analyzers allow to analyze a memory dump (see below).
4747

4848
```bash
4949
$ cd analyzers
50-
$ composer update
50+
$ composer install
5151
```
5252

5353
Usage
5454
-----
55-
All meminfo functions take 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.
56-
57-
## Object instances count per class
58-
Display the number of instances per class, ordered descending. Very useful to identify the content of a memory leak.
59-
60-
```php
61-
meminfo_objects_summary(fopen('php://stdout','w'));
62-
```
55+
The extension has one main function: `meminfo_info_dump`.
6356

64-
The result will provide something similar to the following example generated at the end of a Symfony2 console launch:
57+
This function generates a dump of the PHP memory in a JSON format. This dump can be later analyzed by the provided analyzers.
6558

66-
```
67-
Instances count by class:
68-
num #instances class
69-
-----------------------------------------------------------------
70-
1 181 Symfony\Component\Console\Input\InputOption
71-
2 88 Symfony\Component\Console\Input\InputDefinition
72-
3 77 ReflectionObject
73-
4 46 Symfony\Component\Console\Input\InputArgument
74-
5 2 Symfony\Bridge\Monolog\Logger
75-
6 1 Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher
76-
7 1 Doctrine\Bundle\MigrationsBundle\Command\MigrationsDiffDoctrineCommand
77-
...
78-
```
79-
80-
Note: It's a good idea to call the `gc_collect_cycles()` function before executing `meminfo_objects_summary()`, as it will collect dead objects that has not been reclaimed by the ref counter due to circular references. See http://www.php.net/manual/en/features.gc.php for more details.
81-
82-
83-
### Examples
84-
The `examples/` directory at the root of the repository contains more detailed examples.
85-
```bash
86-
$ php examples/objects_summary.php
87-
```
59+
This functions 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.
8860

89-
## Memory state dump
90-
This feature allow to dump the list of items present in memory at the time of the function execution. Each memory items (string, boolean, objects, array, etc...) are dumped in a JSON format, with the following information:
91-
- in memory address
61+
## Information gathered
62+
Each memory item (string, boolean, objects, array, etc...) is dumped with the following information:
63+
- in-memory address
9264
- type (object, array, int, string, ...)
9365
- class (only for objects)
94-
- object handle (only for objects.
66+
- object handle (only for objects)
9567
- self size (without the size of the linked objects)
96-
- is_root (tells if the item is directly linked to a variable)
97-
- symbol name (variable name, if linked to a variable)
68+
- is_root (tells if the item is directly linked to a declared variable in the PHP program)
69+
- symbol name (name of the variable name in the PHP program, if the item is linked to a variable)
9870
- execution frame (name of the method where the variable has been declared)
99-
- children: list of linked items with the key value if array or property name if object and the item address in memory
71+
- children: list of linked items with the key name in case of array or property name if object, associated to their address in memory
10072

10173
### Dumping memory info
10274
```php
10375
meminfo_info_dump(fopen('/tmp/my_dump_file.json', 'w'));
76+
10477
```
78+
Memory Leak Consequences
79+
------------------------
80+
81+
The main consequences of a memory leak are:
82+
- increasing memory usage
83+
- decreasing performances
84+
85+
Decreasing performances is usually the most visible part. As memory leak saturates the garbage collector buffer, it runs far more often, without being able to free any memory. This leads to a high CPU usage of the process, with a lot of time spent in the garbage collector instead of your code (garbage collector doesn't run in parallel with the user code in PHP, it has to interrupt it).
86+
87+
See https://speakerdeck.com/bitone/hunting-down-memory-leaks-with-php-meminfo for a more detailed insight on how memory leak can occur.
88+
89+
Memory Leak Hunting Process
90+
----------------------------
91+
## Overview
92+
1. dump memory state with `meminfo_info_dump`
93+
2. use the *summary* command of the analyzer to display the item type that is the most present in memory. It's even better to use the summary to display the evolution of objects in memory in order, as the evolution will show where the memory leak really is
94+
3. use the *query* command of the analyzer to find one item from the class that is leaking
95+
4. use the *ref-path* command analyzer to find out the references that still hold this object in memory
96+
97+
## Object Leaks
98+
On object oriented programming, a memory leak usually consists of *objects* leak.
99+
100+
## Memory state dump
105101

106102
### Analyzing a memory dump
107103
The analyzer is available from the `analyzer/` directory. It will be invoked with:
@@ -129,87 +125,12 @@ When you are tracking down a memory leak, it's very interesting to understand wh
129125

130126
The analyzer provides the `ref-path` command that load the memory dump as a graph in memory and findout all paths linking an item to a root (a variable define in an execution frame).
131127

132-
Without the `-v` option, the output will contains only item memory adress and key/property name. Adding the `-v` option will display all the information of the linked items.
128+
Without the `-v` option, the output will contains only item memory address and key/property name. Adding the `-v` option will display all the information of the linked items.
133129

134130
```bash
135131
$ bin/analyzer ref-path my_dump_file.json 0x12345678
136132
```
137133

138-
## List of items in memory
139-
Provides a list of items in memory (objects, arrays, string, etc.) with their sizes.
140-
141-
```php
142-
meminfo_size_info(fopen('php://stdout','w'));
143-
```
144-
145-
For example:
146-
```json
147-
// ...
148-
"0x7fe06ea50a40" : {
149-
"type" : "array",
150-
"size" : "96",
151-
"children" : {
152-
"0":"0x7fe06ea649b0"
153-
}
154-
155-
},
156-
"0x7fe06ea649b0" : {
157-
"type" : "string",
158-
"size" : "99"
159-
160-
},
161-
//...
162-
```
163-
164-
Note: The same remark about `gc_collect_cycles()` before `meminfo_objects_summary()` applies as well for this function.
165-
166-
### Examples
167-
The `examples/` directory at the root of the repository contains more detailed examples.
168-
169-
php examples/size_info.php
170-
171-
##List of currently active objects
172-
Provides a list of live objects with their class and their handle, as well as the total number of active objects and the total number of allocated object buckets.
173-
174-
```php
175-
meminfo_objects_list(fopen('php://stdout','w'));
176-
```
177-
178-
For example:
179-
180-
Objects list:
181-
- Class MyClassB, handle 2, refCount 1
182-
- Class MyClassC, handle 5, refCount 1
183-
- Class MyClassC, handle 6, refCount 1
184-
- Class MyClassC, handle 7, refcount 1
185-
Total object buckets: 7. Current objects: 4.
186-
187-
Note: The same remark about `gc_collect_cycles()` before `meminfo_objects_summary()` applies as well for this function.
188-
189-
### Examples
190-
The `examples/` directory at the root of the repository contains more detailed examples.
191-
192-
php examples/objects_list.php
193-
194-
## Information on structs size
195-
Display size in byte of main data structs size in PHP. Will mainly differ between 32bits et 64bits environments.
196-
197-
```php
198-
meminfo_structs_size(fopen('php://stdout','w'));
199-
```
200-
201-
It can be useful to understand difference in memory usage between two platforms.
202-
203-
Example Output on 64bits environment:
204-
205-
```
206-
Structs size on this platform:
207-
Class (zend_class_entry): 568 bytes.
208-
Object (zend_object): 32 bytes.
209-
Variable (zval): 24 bytes.
210-
Variable value (zvalue_value): 16 bytes.
211-
```
212-
213134
Usage in production
214135
-------------------
215136
PHP Meminfo can be used in production, as it does not have any impact on performances outside of the call to the `meminfo` functions.
@@ -227,12 +148,12 @@ Provides aggregated data about memory usage by functions. Far less resource inte
227148
Troubleshooting
228149
---------------
229150

230-
## "Call to undefined function" when calling meminfo_* functions
151+
## "Call to undefined function" when calling `meminfo_info_dump`
231152
It certainly means the extension is not enabled.
232153

233154
Check the PHP Info output and look for the MemInfo data.
234155

235-
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 command line.
156+
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.
236157

237158
Credits
238159
-------

0 commit comments

Comments
 (0)