php-memprof es una extensión de creación de perfiles de memoria rápida y precisa para PHP que se puede utilizar para encontrar la causa de las pérdidas de memoria.
La extensión rastrea la asignación y liberación de bloques de memoria para informar la cantidad de memoria perdida por cada función, método o archivo de un programa.
Informa memoria no liberada en puntos arbitrarios del programa.
Vuelca el perfil en formatos callgrind, pprof o raw array
Puede rastrear la memoria asignada por el propio PHP, así como por el malloc nativo
php-memprof depende de libjudy y sys/queue.h.
En distribuciones basadas en Debian las dependencias se pueden instalar con:
# Debian or Ubuntu: apt install libjudy-dev
En alpino:
# Alpine apk add judy-dev bsd-compat-headers
En Mac OS:
# install libjudy dependency: brew install traildb/judy/judy
Asegúrese de instalar las dependencias y luego:
pecl install memprof
En MacOS: JUDY_DIR=$(brew --prefix traildb/judy/judy) pecl install memprof
Nota Si libjudy está instalado en una ruta no estándar (no /usr o /usr/local), utilice el método de instalación manual a continuación.
Asegúrese de instalar las dependencias y luego:
Descargue el código fuente y ejecute los siguientes comandos en el directorio de origen:
phpize ./configure make make install
Nota Si libjudy está instalado en una ruta no estándar (no /usr o /usr/local), puede especificarlo de esta manera:
./configure --with-judy-dir=/opt/homebrew/Cellar/judy/1.0.5
Los usuarios de Arch Linux pueden preferir instalar el paquete no oficial php-memprof con makepkg
o su ayudante AUR preferido. Si usa yay
, por ejemplo:
yay -S php-memprof
Informe cualquier problema con este paquete en su página AUR.
La extensión se puede cargar en la línea de comando, solo para un script:
php -dextension=memprof.so script.php
O permanentemente, en php.ini:
extension=memprof.so
La extensión no tiene gastos generales cuando no se genera un perfil, por lo que se puede cargar de forma predeterminada en entornos de desarrollo.
La forma más sencilla de utilizar memprof
es dejar que guarde el perfil de memoria cuando se excede el límite de memoria del programa.
dump_on_limit
La creación de perfiles en modo dump_on_limit
se habilita al inicio de la solicitud cuando uno de estos es verdadero:
La variable de entorno MEMPROF_PROFILE
es igual a dump_on_limit
$_GET["MEMPROF_PROFILE"]
es igual a dump_on_limit
$_POST["MEMPROF_PROFILE"]
es igual a dump_on_limit
Para scripts de línea de comando, podemos configurar la variable de entorno:
MEMPROF_PROFILE=dump_on_limit php test.php
Para scripts web, podemos configurar la variable $_GET
:
curl http://127.0.0.1/test.php?MEMPROF_PROFILE=dump_on_limit
O la variable $_POST
:
curl -d MEMPROF_PROFILE=dump_on_limit http://127.0.0.1/test.php
Nota Se puede llamar a la función
memprof_enabled_flags()
para comprobar si la creación de perfiles está actualmente habilitada en el mododump_on_limit
.
En este modo, memprof
guardará automáticamente el perfil si el programa excede el límite de memoria (cuando PHP desencadena un error como Fatal error: Allowed memory size of 15728640 bytes exhausted (tried to allocate 1024 bytes)
).
De forma predeterminada, el perfil se guarda en un archivo llamado memprof.callgrind.*
en /tmp
o C:WindowsTemp
.
La forma recomendada de visualizar el resultado es utilizar Kcachegrind (en Linux) o Qcachegrind (en MacOS, Windows). También se admiten Google Perftools. Consulte la documentación de memprof_dump_callgrind()
y variantes.
La mayoría de las distribuciones tienen un paquete kcachegrind
listo para ser instalado.
Por ejemplo, Ubuntu o Debian:
sudo apt install kcachegrind
Es muy probable que otras distribuciones también tengan un paquete listo para instalar.
Utilice Homebrew: https://formulae.brew.sh/formula/qcachegrind
Descárgalo desde https://sourceforge.net/projects/qcachegrindwin/
La creación de perfiles se habilita al inicio de la solicitud cuando una de estas condiciones es verdadera:
La variable de entorno MEMPROF_PROFILE
no está vacía
$_GET["MEMPROF_PROFILE"]
no está vacío
$_POST["MEMPROF_PROFILE"]
no está vacío
La variable MEMPROF_PROFILE
acepta una lista de indicadores separados por comas.
Ejemplos de valores MEMPROF_PROFILE
válidos:
1
: no vacío: la creación de perfiles está habilitada
dump_on_limit
: la creación de perfiles está habilitada, se volcará según el límite de memoria
native
: la creación de perfiles está habilitada, perfilará las asignaciones nativas
dump_on_limit,native
: la creación de perfiles está habilitada, perfilará las asignaciones nativas, volcará el límite de memoria
Lista de banderas válidas:
dump_on_limit
: volcará el perfil en formato callgrind en /tmp
o C:WindowsTemp
. El directorio de salida se puede cambiar con la configuración ini memprof.output_dir
.
native
: perfilará las asignaciones nativas malloc()
, no solo las de PHP (esto no es seguro para subprocesos, consulte a continuación).
Memprof no realiza un seguimiento de las asignaciones nativas de forma predeterminada, pero esto se puede habilitar configurando MEMPROF_PROFILE
en native
.
Las asignaciones nativas son las asignaciones realizadas fuera del propio asignador de memoria de PHP. Normalmente, las bibliotecas externas como libxml2 (utilizada en la extensión DOM) realizan asignaciones nativas. PHP también puede realizar asignaciones nativas para recursos persistentes.
Habilitar el seguimiento de asignaciones nativas generará un perfil de estas asignaciones además de las propias asignaciones de PHP.
Tenga en cuenta que cuando el seguimiento nativo está habilitado, el programa fallará si una biblioteca nativa usa subprocesos, porque los enlaces subyacentes no son seguros para subprocesos.
El formato del archivo de salida se define con la configuración ini memprof.output_format
. Las opciones son:
callgrind
(predeterminado)
pprof
Nota : es posible que esto solo esté disponible cuando la extensión se compila desde el código fuente (y no se instala con pecl), a partir del n.° 101.
Devuelve si la creación de perfiles de memoria está actualmente habilitada (ver arriba).
Devuelve si la creación de perfiles de memoria y qué funciones de creación de perfiles están habilitadas (ver arriba).
Vuelca el perfil actual en formato callgrind. El resultado se puede visualizar con herramientas como KCacheGrind o QCacheGrind.
<phpmemprof_dump_callgrind(fopen("salida", "w"));
Aquí hay una captura de pantalla de QcacheGrind:
Vuelca el perfil actual en formato pprof.
<?phpmemprof_dump_pprof(fopen("profile.heap", "w"));
El archivo se puede visualizar con la herramienta pprof
de google-perftools. (Consulte las instrucciones de instalación a continuación).
Muestra el gráfico de llamadas anotado en el navegador web o en gv
:
$ pprof --web profile.heap $ # or: $ pprof --gv profile.heap
Genere una línea por función, ordenada por uso de memoria propia:
$ pprof --text profile.heap
pprof
: Ubuntu: apt install google-perftools
. En Ubuntu, la herramienta se llama google-pprof
, por lo que debes reemplazar pprof
con google-pprof
en los ejemplos anteriores.
Devuelve una matriz que representa el perfil actual.
<php$dump = memprof_dump_array();
La matriz expone la siguiente información:
Memoria inclusiva y exclusiva filtrada por funciones (contando solo la memoria que aún no se libera cuando se llama a memprof_dump_array)
Recuento de funciones de bloques inclusivos y exclusivos (número de asignaciones; contando solo los bloques que aún no se liberan cuando se llama a memprof_dump_array)
Los datos se presentan en pilas de llamadas. De esta manera, si se llama a una función desde varios lugares, es posible ver qué ruta de llamada provocó que perdiera más memoria.
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 ( ) ) ) ) ) )
Devuelve la versión de la extensión como una cadena. La versión se puede comparar con version_compare().
Las extensiones pueden entrar en conflicto con xdebug, blackfire u otras extensiones. Si ese es tu caso, por favor repórtalo.
La rama actual admite PHP 7.1 a PHP 8.
La rama php5 es compatible con PHP 5.
Ver INTERNOS.md