2010-11-26 16 views
10

Aún no he encontrado una solución elegante para esto. Tengo una clase con un método que quiero hacer un seguimiento del uso de la memoria de la función sin modificar:Uso de la memoria de seguimiento de un método

class Example 
{ 
    public function hello($name) 
    { 
     $something = str_repeat($name, pow(1024, 2)); 
    } 
} 

$class = new Example; 
$class->hello('a'); 

Así que la tarea es, la cantidad de memoria hace hello() uso sin interferir con ella?

Nota: El uso de memoria de este método debe ser de 1 MB. He intentado envolver la llamada con memory_get_usage(); en vano:

class Example 
{ 
    public function hello($name) 
    { 
     $something = str_repeat($name, pow(1024, 2)); 
    } 
} 

$class = new Example; 

$s = memory_get_usage(); 

$class->hello('a'); 

echo memory_get_usage() - $s; 

Esto sólo da lugar a 144 bytes (no es correcto en absoluto). He intentado varias magias con Reflection usando la clase ReflectionMethod.

Tengo la sensación de lo que tengo que hacer es calcular la diferencia en el método :(Si alguien se le ocurre nada más limpia entonces lo que realmente hace que mi día

Editar:.. debería mencionar esto es en el contexto de una aplicación de evaluación comparativa. Por lo tanto, aunque memory_get_peak_usage funciona en el sentido de que devuelve correctamente el uso de la memoria, también sesgará las pruebas ejecutadas después de un método de memoria alta. Ahora, si había una manera de restablecer las estadísticas de la memoria, podría ser bueno también.

+0

+1 y buena suerte para encontrar una respuesta – alex

+0

¿Qué necesita el uso de memoria para? Sólo curioso. –

+0

Estoy tratando de arreglar un error con una biblioteca llamada CodeBench. http://img833.imageshack.us/img833/3306/selection006p.png y algún código: https://github.com/kohana/codebench/blob/3.0.x/classes/kohana/codebench.php#L103 –

Respuesta

5

Puede usar register_tick_function y simplemente descargar memeory_get_usage cada tick (línea) y analizarlo más tarde. La clase a continuación podría mejorarse usando debug_backtrace para encontrar el número de línea relacionado con el uso de memoria o agregando tiempo por línea usando microtime.

clase Profiler

class Profiler 
{ 

    private $_data_array = array(); 

    function __construct() 
    { 
     register_tick_function(array($this, "tick")); 
     declare(ticks = 1); 
    } 

    function __destruct() 
    { 
     unregister_tick_function(array($this, "tick")); 
    } 

    function tick() 
    { 
     $this->_data_array[] = array(
      "memory" => memory_get_usage(), 
      "time" => microtime(TRUE), 
      //if you need a backtrace you can uncomment this next line 
      //"backtrace" => debug_backtrace(FALSE), 
     ); 
    } 

    function getDataArray() 
    { 
     return $this->_data_array; 
    } 
} 

Ejemplo

class Example 
{ 
    public function hello($name) 
    { 
     $something = str_repeat($name, pow(1024, 2)); 
    } 
} 

$profiler = new Profiler(); //starts logging when created 

$class = new Example; 
$class->hello('a'); 

$data_array = $profiler->getDataArray(); 

unset($profiler); //stops logging when __destruct is called 

print_r($data_array); 

salida

Array (
    [0] => Array (
      [memory] => 638088 
      [time] => 1290788749.72 
     ) 
    [1] => Array (
      [memory] => 638896 
      [time] => 1290788749.72 
     ) 
    [2] => Array (
      [memory] => 639536 
      [time] => 1290788749.72 
     ) 
    [3] => Array (
      [memory] => 640480 
      [time] => 1290788749.72 
     ) 
    [4] => Array (
      [memory] => 1689800 // <~ money! 
      [time] => 1290788749.72 
     ) 
    [5] => Array (
      [memory] => 641664 
      [time] => 1290788749.72 
     ) 
) 

Número posible

Dado que esta clase de generador de perfiles almacena los datos en PHP, el uso general de la memoria aumentará artificialmente. Una forma de eludir este problema sería escribir los datos en un archivo a medida que avanza (serializado), y cuando haya terminado puede leerlo nuevamente.

+0

Con un poco de trabajo, esto es bueno. Gracias por la solución creativa, no creo que encontremos una respuesta mejor :-) Aceptada. –

+0

@The Pixel Developer Gracias –

0

Parece que ya ha 'liberado' la memoria después de que la llamada a hello() haya finalizado.

¿Cuáles son los resultados cuando lo hace:

$s = memory_get_usage(); 

$class->hello('a'); 

echo memory_get_peak_usage() - $s; 
+0

I He añadido un comentario sobre memory_get_peak_usage(), gracias. –

1

La memoria se libera cuando regrese de la función.

Puede agregar el $s = memory_get_usage(); ... echo memory_get_usage() - $s; bloque dentro de la función. De esta forma, la memoria utilizada no se liberará.

2

El perfilador XHProfLive desarrollado por los chicos de Facebook da este grado de perfil de función/método, y está disponible como PECL download.

Cuestiones relacionadas