2011-05-11 12 views
11

me preguntaba cuándo PHP libera la memoria que se utiliza durante las variables¿Cómo asigna PHP y libera memoria para las variables?

por ejemplo

function foo(){ 
    $foo = 'data'; 
    return $foo; // <- is the memory space for `$foo` emptied at this point? 
} 

es más lento que:

function foo(){ 
    return 'data'; 
} 

?

+0

¿Podemos preguntar por qué estás preguntando? IIRC, el Zend Engine subyacente utiliza copy-on-write, por lo que probablemente no importe en la mayoría de los casos. ¿Estás saliendo de problemas de memoria? – Charles

+1

* (referencia) * [Recolección de basura] (http://de.php.net/manual/en/features.gc.php) – Gordon

+0

no, solo tengo curiosidad :) pero admito que tus respuestas pueden influir en mi estilo de codificación en el futuro :) – Alex

Respuesta

9

Bueno, vamos a descubrirlo!

<?php 
$checkpoints = array('start' => memory_get_usage()); 

$checkpoints['before defining demo1'] = memory_get_usage(); 
function demo1() { $foo = 'data'; return $foo; } 
$checkpoints['after defining demo1'] = memory_get_usage(); 

$checkpoints['before defining demo2'] = memory_get_usage(); 
function demo2() { return 'data'; } 
$checkpoints['after defining demo2'] = memory_get_usage(); 


$checkpoints['before calling demo1'] = memory_get_usage(); 
demo1(); 
$checkpoints['after calling demo1'] = memory_get_usage(); 

$checkpoints['before calling demo2'] = memory_get_usage(); 
demo2(); 
$checkpoints['after calling demo2'] = memory_get_usage(); 

$checkpoints['before calling demo1 with storage'] = memory_get_usage(); 
$storage1 = demo1(); 
$checkpoints['after calling demo1 with storage'] = memory_get_usage(); 

$checkpoints['before calling demo2 with storage'] = memory_get_usage(); 
$storage2 = demo2(); 
$checkpoints['after calling demo2 with storage'] = memory_get_usage(); 

echo '<pre>'; 
print_r($checkpoints); 

$last_key = 'start'; 
foreach($checkpoints as $key => $value) { 
    echo "{$key} - {$last_key} = ", ($value - $checkpoints[$last_key]), "\n"; 
    $last_key = $key; 
} 

En PHP 5.3.6, mi salida es:

Array 
(
    [start] => 321920 
    [before defining demo1] => 322188 
    [after defining demo1] => 322788 
    [before defining demo2] => 322880 
    [after defining demo2] => 323188 
    [before calling demo1] => 323280 
    [after calling demo1] => 323368 
    [before calling demo2] => 323464 
    [after calling demo2] => 323552 
    [before calling demo1 with storage] => 323692 
    [after calling demo1 with storage] => 323896 
    [before calling demo2 with storage] => 324000 
    [after calling demo2 with storage] => 324204 
) 

y luego

start - start = 0 
before defining demo1 - start = 268 
after defining demo1 - before defining demo1 = 600 
before defining demo2 - after defining demo1 = 92 
after defining demo2 - before defining demo2 = 308 
before calling demo1 - after defining demo2 = 92 
after calling demo1 - before calling demo1 = 88 
before calling demo2 - after calling demo1 = 96 
after calling demo2 - before calling demo2 = 88 
before calling demo1 with storage - after calling demo2 = 140 
after calling demo1 with storage - before calling demo1 with storage = 204 
before calling demo2 with storage - after calling demo1 with storage = 104 
after calling demo2 with storage - before calling demo2 with storage = 204 

Es muy probable que el aumento de memoria durante las llamadas iniciales a demo1demo2 y que descartan el resultado se debe a la creación de variables para almacenar el uso de la memoria.

Sin embargo, el fondo aquí es los dos ejemplos de almacenamiento, donde ambos regresan datos directamente y asignar a una variable antes de devolverlo resultó en el mismo uso de memoria exacta para los datos dados.

Conclusión: PHP parece lo suficientemente inteligente como en esta sencilla prueba para copiar no innecesariamente variables de cadena - a pesar de hacer mantener un ojo en la diferencia de uso de memoria entre las dos funciones. Solo al declarar que la función demo1 tomó más memoria que declarar demo2. Algunos cientos de bytes, realmente.

+0

muchas gracias. Creo que usaré el segundo método siempre que pueda: D – Alex

Cuestiones relacionadas