2010-02-22 9 views
12

Aquí está mi código, que crea matriz 2D lleno de ceros, dimensiones de la matriz son (795,6942):Problemas con PHP al intentar crear gran variedad

function zeros($rowCount, $colCount){ 
    $matrix = array(); 
    for ($rowIndx=0; $rowIndx<$rowCount; $rowIndx++){ 
     $matrix[] = array(); 
     for($colIndx=0; $colIndx<$colCount; $colIndx++){ 
      $matrix[$rowIndx][$colIndx]=0; 
     } 
    } 
    return $matrix; 
} 

$matrix = zeros(795,6942); 

Y aquí es el error que recibo:

Allowed memory size of 134217728 bytes exhausted (tried to allocate 35 bytes) 

¿Alguna idea de cómo solucionar esto?

+0

Dado que está creando una matriz llena cero en la memoria, supongo que desea ejecutar algunas operaciones en esto. En ese caso, ¿por qué no usas un almacén de datos como Redis? Tendrá datos enormes con una pequeña sobrecarga para php. Y puede ejecutar operaciones con un riesgo de rendimiento insignificante. – mixdev

Respuesta

27

Como un cálculo rápido, que están tratando de crear una matriz que contiene:

795*6942 = 5,518,890 

enteros.

Si consideramos que un número entero se almacena en 4 bytes (es decir, 32 bits; usando PHP, que no sea menos), significa:

5518890*4 = 22,075,560 

bytes.

OK, cálculo rápido ... el resultado es "debería estar bien".

Pero las cosas no son tan fáciles, por desgracia :-(
supongo que está relacionado con el hecho de que los datos se almacenan por PHP utilizando una estructura de datos interna que es mucho más complicado que una llanura de 32 bits enteros


Ahora, sólo para sentir curiosidad, vamos a modificar su función por lo que da salida a la cantidad de memoria utilizada al final de cada uno de los lazos en forma externa for:

function zeros($rowCount, $colCount){ 
    $matrix = array(); 
    for ($rowIndx=0; $rowIndx<$rowCount; $rowIndx++){ 
     $matrix[] = array(); 
     for($colIndx=0; $colIndx<$colCount; $colIndx++){ 
      $matrix[$rowIndx][$colIndx]=0; 
     } 
     var_dump(memory_get_usage()); 
    } 
    return $matrix; 
} 

Con esto, obtengo este tipo de salida (PHP 5.3.2-dev en un sistema de 64 bits; memory_limit se establece en 128MB - que ya es mucho):

int 1631968 
int 2641888 
int 3651808 
... 
... 
int 132924168 
int 133934088 
Fatal error: Allowed memory size of 134217728 bytes exhausted 

Lo que significa que cada iteración del for lazos en forma externa requiere algo así como 1,5 MB de memoria - y solo me dan a 131 iteraciones antes! el script se queda sin memoria; y no 765 como querías.

Está considerando establecer su memory_limit-128M, tendría que ponerlo en algo realmente mucho más alta - como

128*(765/131) = 747 MB 

Bueno, incluso con

ini_set('memory_limit', '750M'); 

todavía no es suficiente. ..con 800MB, parece suficiente ;-)


Pero definitivamente no recomendaría el establecimiento memory_limit a un valor tan alto!

(Si usted tiene 2 GB de RAM, su servidor no va a ser capaz de manejar más de 2 usuarios concurrentes ^^ ;; yo no realmente probar esto si mi equipo tiene 2 GB de RAM, para ser honesto)


La única solución que veo aquí es para que usted pueda volver a pensar su diseño: tiene que haber algo más que puede hacer que use esta porción de código :-)

(por cierto: tal vez " volver a pensar su diseño "significa usar otro idioma PHP: PHP es excelente cuando se trata de desarrollar sitios web, pero no es adecuado para todo tipo de problema)

1

usted debe tratar de aumentar la cantidad de memoria disponible para PHP:

ini_set('memory_limit', '32M'); 

en su archivo PHP.

+2

128M está configurado de manera predeterminada – spacemonkey

5

La implementación predeterminada de la matriz PHP requiere mucha memoria. Si solo está almacenando enteros (y muchos de ellos), probablemente quiera mirar SplFixedArray. Utiliza un bloque de memoria contiguo regular para almacenar los datos, a diferencia de la estructura hash tradicional.

Cuestiones relacionadas