¿Existe una función en PHP (o una extensión de PHP) para averiguar cuánta memoria usa una variable determinada? sizeof
solo me dice el número de elementos / propiedades.
memory_get_usage
ayuda porque me da el tamaño de memoria utilizado por todo el script. ¿Hay alguna forma de hacer esto para una sola variable?
Tenga en cuenta que esto está en una máquina de desarrollo, por lo que es factible cargar extensiones o herramientas de depuración.
Respuestas:
Probablemente necesite un Memory Profiler. He recopilado información para SO, pero he copiado algo importante que también puede ayudarlo.
Como probablemente sepa, Xdebug eliminó el soporte de creación de perfiles de memoria desde la versión 2. *. Busque la cadena "funciones eliminadas" aquí: http://www.xdebug.org/updates.php
Otras opciones del generador de perfiles
php-memory-profiler
https://github.com/arnaud-lb/php-memory-profiler . Esto es lo que hice en mi servidor Ubuntu para habilitarlo:
Y luego en mi código:
Finalmente abra el
callgrind.out
archivo con KCachegrindUsando Google gperftools (¡recomendado!)
En primer lugar, instale Google gperftools descargando el último paquete aquí: https://code.google.com/p/gperftools/
Entonces, como siempre:
Ahora en tu código:
Luego abre tu terminal y lanza:
pprof creará una nueva ventana en su sesión de navegador existente con algo como se muestra a continuación:
Xhprof + Xhgui (el mejor en mi opinión para perfilar tanto la CPU como la memoria)
Con Xhprof y Xhgui también puede perfilar el uso de la CPU o solo el uso de la memoria si ese es su problema en este momento. Es una solución muy completa, le brinda control total y los registros se pueden escribir tanto en mongo como en el sistema de archivos.
Para obtener más detalles, consulte aquí .
Fuego negro
Blackfire es un generador de perfiles PHP de SensioLabs, los chicos de Symfony2 https://blackfire.io/
Si usa puphpet para configurar su máquina virtual, le alegrará saber que es compatible ;-)
Xdebug y seguimiento del uso de memoria
XDEBUG2 es una extensión para PHP. Xdebug le permite registrar todas las llamadas a funciones, incluidos los parámetros y los valores de retorno, a un archivo en diferentes formatos. Hay tres formatos de salida. Uno está destinado a ser un rastro legible por humanos, otro es más adecuado para programas de computadora ya que es más fácil de analizar, y el último utiliza HTML para formatear el rastro. Puede cambiar entre los dos formatos diferentes con la configuración. Un ejemplo estaría disponible aquí
para p
forp simple, no intrusivo, orientado a la producción, perfilador PHP. Algunas de las características son:
medición de tiempo y memoria asignada para cada función
uso de CPU
archivo y número de línea de la llamada a la función
salida como formato de evento de seguimiento de Google
título de funciones
agrupación de funciones
alias de funciones (útil para funciones anónimas)
DBG
DBG es un depurador php con todas las funciones, una herramienta interactiva que le ayuda a depurar scripts php. Funciona en un servidor WEB de producción y / o desarrollo y te permite depurar tus scripts de forma local o remota, desde un IDE o consola y sus características son:
Depuración local y remota
Activación explícita e implícita
Pila de llamadas, incluidas las llamadas a funciones, llamadas a métodos dinámicos y estáticos, con sus parámetros
Navegación a través de la pila de llamadas con capacidad para evaluar variables en los lugares correspondientes (anidados)
Entrar / Salir / Pasar por encima / Ejecutar hasta la funcionalidad del cursor
Puntos de interrupción condicionales
Puntos de interrupción globales
Registro de errores y advertencias
Varias sesiones simultáneas para depuración paralela
Soporte para interfaces GUI y CLI
Soporta redes IPv6 e IPv4
Todos los datos transferidos por el depurador pueden protegerse opcionalmente con SSL
fuente
No hay una forma directa de obtener el uso de memoria de una sola variable, pero como sugirió Gordon, puede usar
memory_get_usage
. Eso devolverá la cantidad total de memoria asignada, por lo que puede usar una solución alternativa y medir el uso antes y después para obtener el uso de una sola variable. Esto es un poco complicado, pero debería funcionar.Tenga en cuenta que este no es un método confiable de ninguna manera, no puede estar seguro de que nada más toque la memoria al asignar la variable, por lo que esto solo debe usarse como una aproximación.
De hecho, puede convertir eso en una función creando una copia de la variable dentro de la función y midiendo la memoria utilizada. No he probado esto, pero en principio, no veo nada malo en ello:
fuente
$tmp = $var
creará una copia superficial. Esto no asignará más memoria hasta que se modifique $ tmp.$tmp = unserialize(serialize($var))
; Esto combinaría el enfoque de Aistina anterior.$var
que ya es una copia superficial o una referencia de lo que se pasó a la función, no es necesario$tmp
, pero puede reasignarlo$var
. Esto guarda la referencia interna de$tmp
a$var
.$tmp
a partir$var
?No no hay. Pero puede
serialize($var)
y verifiquestrlen
el resultado para una aproximación.fuente
strlen(serialize(array(1,2,3)))
tiene 30.En respuesta a la respuesta de Tatu Ulmanens:
Cabe señalar que en
$start_memory
sí mismo ocupará memoria (PHP_INT_SIZE * 8
).Entonces toda la función debería convertirse en:
Lamento agregar esto como una respuesta adicional, pero aún no puedo comentar una respuesta.
Actualización: El * 8 no está definido. Aparentemente, puede depender de la versión de php y posiblemente de 64/32 bits.
fuente
* 8
? ¡Gracias!PHP_INT_SIZE
bytes, sino quePHP_INT_SIZE*8
. Puede intentarlo llamando a esta función, debería devolver 0:function sizeofvar() { $start_memory = memory_get_usage(); return memory_get_usage() - $start_memory - PHP_INT_SIZE*8; }
8
no parece constante. Siguiendo su función de comentario en mi sistema de desarrollo (PHP 5.6.19), regresa-16
. Además, curiosamente,php -a
llamar a las dos líneas de la función da varios valores diferentes.Ver:
memory_get_usage()
- Devuelve la cantidad de memoria asignada a PHPmemory_get_peak_usage()
- Devuelve el pico de memoria asignado por PHPSin embargo, tenga en cuenta que esto no le dará el uso de memoria de una variable específica. Pero puede realizar llamadas a estas funciones antes y después de asignar la variable y luego comparar los valores. Eso debería darle una idea de la memoria utilizada.
También puede echar un vistazo a la extensión Memtrack de PECL , aunque la documentación es un poco escasa, por no decir prácticamente inexistente.
fuente
Puede optar por calcular la diferencia de memoria en un valor de devolución de llamada. Es una solución más elegante disponible en PHP 5.3+.
fuente
No se puede calcular retrospectivamente la huella exacta de una variable, ya que dos variables pueden compartir el mismo espacio asignado en la memoria.
Intentemos compartir memoria entre dos matrices, vemos que asignar la segunda matriz cuesta la mitad de la memoria de la primera. Cuando desarmamos el primero, el segundo todavía usa casi toda la memoria.
Entonces, no podemos concluir que la segunda matriz usa la mitad de la memoria, ya que se vuelve falsa cuando desarmamos la primera.
Para obtener una vista completa de cómo se asigna la memoria en PHP y para qué uso, le sugiero que lea el siguiente artículo: ¿Qué tan grandes son realmente las matrices (y valores) de PHP? (Pista: ¡GRANDE!)
Los conceptos básicos del recuento de referencias en la documentación de PHP también tienen mucha información sobre el uso de la memoria y el recuento de referencias al segmento de datos compartidos.
Las diferentes soluciones expuestas aquí son buenas para aproximaciones, pero ninguna puede manejar la administración sutil de la memoria PHP.
Si desea el espacio recién asignado después de una asignación, entonces debe usarlo
memory_get_usage()
antes y después de la asignación, ya que usarlo con una copia le da una visión errónea de la realidad.Recuerda que si quieres almacenar el resultado del primero
memory_get_usage()
, la variable ya tiene que existir antes, ymemory_get_usage()
debe ser llamada otra vez antes, y todas las demás funciones también.Si desea hacer eco como en el ejemplo anterior, su búfer de salida ya debe estar abierto para evitar la memoria de contabilidad necesaria para abrir el búfer de salida.
Si desea confiar en una función para calcular el espacio requerido para almacenar una copia de una variable, el siguiente código se encarga de diferentes optimizaciones:
Tenga en cuenta que el tamaño del nombre de la variable importa en la memoria asignada.
Una variable tiene un tamaño básico definido por la estructura interna de C utilizada en el código fuente PHP. Este tamaño no fluctúa en el caso de los números. Para cadenas, agregaría la longitud de la cadena.
Si no tenemos en cuenta la inicialización del nombre de la variable, ya sabemos cuánto utiliza una variable (en el caso de números y cadenas):
(esos números pueden cambiar según la versión de PHP)
Tiene que redondear a un múltiplo de 4 bytes debido a la alineación de la memoria. Si la variable está en el espacio global (no dentro de una función), también asignará 64 bytes más.
Entonces, si desea usar uno de los códigos dentro de esta página, debe verificar que el resultado usando algunos casos de prueba simples (cadenas o números) coincida con esos datos teniendo en cuenta cada una de las indicaciones en esta publicación ($ _GLOBAL array, primera llamada de función, búfer de salida, ...)
fuente
zvalue
,is_ref
y copia en escritura. Gracias.Tuve un problema similar, y la solución que usé fue escribir la variable en un archivo y luego ejecutar () en él. Más o menos así (código no probado):
Esta solución no es terriblemente rápida porque implica E / S de disco, pero debería darte algo mucho más exacto que los trucos memory_get_usage. Solo depende de cuánta precisión requiera.
fuente
strlen
sería más fácil.Nunca lo intenté, pero los seguimientos de Xdebug con xdebug.collect_assignment s pueden ser suficientes.
fuente
fuente
El siguiente script muestra el uso total de memoria de una sola variable.
Mira esto
http://www.phpzag.com/how-much-memory-do-php-variables-use/
fuente