tried - php exhausted memory
Error grave: tamaƱo de memoria permitido de 134217728 bytes agotados(CodeIgniter+XML-RPC) (23)
Tengo un montón de sistemas de punto de venta (POS) que envían periódicamente nuevos datos de ventas a una base de datos centralizada, que almacena los datos en una gran base de datos para la generación de informes.
El TPV del cliente se basa en PHPPOS y he implementado un módulo que utiliza la biblioteca estándar de XML-RPC para enviar datos de ventas al servicio. El sistema del servidor se basa en CodeIgniter y utiliza las bibliotecas XML-RPC y XML-RPCS para el componente de servicio web. Siempre que envío muchos datos de ventas (tan poco como 50 filas de la tabla de ventas, y filas individuales de sales_items pertenecientes a cada artículo dentro de la venta) obtengo el siguiente error:
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 54 bytes)
128M es el valor predeterminado en php.ini
, pero supongo que es un número enorme para romper. De hecho, incluso he intentado establecer este valor en 1024M, y todo lo que hace es tardar más en salir.
En cuanto a los pasos que he tomado, he intentado deshabilitar todo el procesamiento en el lado del servidor y lo he manipulado para que devuelva una respuesta enlatada independientemente de la entrada. Sin embargo, creo que el problema radica en el envío real de los datos. Incluso he intentado deshabilitar el tiempo máximo de ejecución de scripts para PHP, y aún se producen errores.
Cambie el límite de memoria del archivo php.ini y reinicie Apache. Después de reiniciar ejecuta el phpinfo (); Funciona desde cualquier archivo php para la confirmación de cambio de memory_limit.
memory_limit = -1
el límite de memoria -1 significa que no hay un límite de memoria establecido, ahora es el máximo.
Al agregar 22.5 millones de registros en una matriz con array_push, seguí obteniendo errores fatales de "memoria agotada" en alrededor de 20M de registros usando 4G como límite de memoria en php.ini. Para arreglar esto agregué la declaración.
$old = ini_set(''memory_limit'', ''8192M'');
en la parte superior del archivo. Ahora todo está funcionando bien. No sé si php tiene una pérdida de memoria, ese no es mi trabajo, ni me importa. Solo tengo que hacer mi trabajo, y esto funcionó.
El programa es muy simple:
$fh = fopen($myfile);
while (!feof($fh)) {
array_push($file, stripslashes(fgets($fh)));
}
fclose($fh);
El error fatal apunta a la línea 3 hasta que aumenté el límite de memoria, lo que eliminó el error.
Cambiar el memory_limit
de memory_limit
por ini_set(''memory_limit'', ''-1'');
No es una solución adecuada. Por favor no hagas eso.
Su código PHP puede tener una pérdida de memoria en algún lugar y le está diciendo al servidor que solo use toda la memoria que desee. No habrías solucionado el problema en absoluto. Si supervisa su servidor, verá que ahora probablemente esté usando la mayor parte de la RAM e incluso cambiando a disco.
Probablemente debería intentar rastrear el código ofensivo en su código y repararlo.
Cuando ve el error anterior, especialmente si el (tried to allocate __ bytes)
es un valor bajo, podría ser un indicador de un bucle infinito, como una función que se llama a sí misma sin salida:
function exhaustYourBytes()
{
return exhaustYourBytes();
}
Después de habilitar estas dos líneas.
Ha comenzado a trabajar
; Determines the size of the realpath cache to be used by PHP. This value should
; be increased on systems where PHP opens many files to reflect the quantity of
; the file operations performed.
; http://php.net/realpath-cache-size
realpath_cache_size = 16k
; Duration of time, in seconds for which to cache realpath information for a given
; file or directory. For systems with rarely changing files, consider increasing this
; value.
; http://php.net/realpath-cache-ttl
realpath_cache_ttl = 120
Ejecutar el script de esta manera (caso de cron, por ejemplo): php5 /pathToScript/info.php
produce el mismo error.
La forma correcta: php5 -cli /pathToScript/info.php
En Drupal 7, puede modificar el límite de memoria en el archivo settings.php ubicado en su carpeta de sitios / predeterminada. Alrededor de la línea 260, verá esto:
ini_set(''memory_limit'', ''128M'');
Incluso si su configuración de php.ini es lo suficientemente alta, no podrá consumir más de 128 MB si esto no está establecido en su archivo de configuración de Drupal.php.
En lugar de cambiar el valor de memory_limit
en su archivo php.ini
, si hay una parte de su código que podría usar una gran cantidad de memoria, puede eliminar memory_limit
antes de que se ejecute esa sección, y luego reemplazarla.
$limit = ini_get(''memory_limit'');
ini_set(''memory_limit'', -1);
// ... do heavy stuff
ini_set(''memory_limit'', $limit);
Es muy fácil obtener pérdidas de memoria en un script PHP, especialmente si usa abstracción, como un ORM. Intente usar Xdebug para crear un perfil de su secuencia de comandos y averiguar dónde se fue toda esa memoria.
La asignación de memoria para PHP se puede ajustar de forma permanente o temporal.
Permanentemente
Puede cambiar permanentemente la asignación de memoria PHP de dos maneras.
Si tiene acceso a su archivo php.ini
, puede editar el valor de memory_limit
a su valor memory_limit
.
Si no tiene acceso a su archivo php.ini
(y su servidor web lo permite), puede anular la asignación de memoria a través de su archivo .htaccess
. Agregue php_value memory_limit 128M
(o cualquiera que sea su asignación deseada).
Temporal
Puede ajustar la asignación de memoria sobre la marcha desde un archivo PHP. Simplemente tiene el código ini_set(''memory_limit'', ''128M'');
(o cualquiera que sea su asignación deseada). Puede eliminar el límite de memoria (aunque aún pueden aplicarse los límites de la máquina o la instancia) estableciendo el valor en "-1".
La forma correcta es editar su archivo php.ini
. Edite memory_limit
a su valor memory_limit
.
A partir de su pregunta, se ha excedido 128M
(que es el límite predeterminado), por lo que hay un error grave en su código, ya que no debería tomar mucho.
Si sabe por qué se necesita mucho y desea permitirlo, establezca memory_limit = 512M
o superior y debería ser bueno.
Me parece útil cuando se incluye o requiere:
dbconnection.php , _functions.php en archivos que realmente se procesan,
en lugar de incluir en el encabezado. Que se incluye a sí mismo.
Entonces, si se incluyen su encabezado y pie de página , simplemente incluya todos sus archivos funcionales antes de incluir el encabezado.
No estoy seguro si esta respuesta será de alguna ayuda, pero cuando eliminé las siguientes líneas de mi código, ¡todo funcionó bien!
set_include_path(get_include_path() . get_include_path().''/phpseclib'');
include_once (''Net / SSH2.php''); include_once (''Net / SFTP.php'');
Estas líneas se incluyeron en todos los archivos que se ejecutan, cuando los archivos de uno en uno funcionaron bien, pero cuando se ejecutaron todos los archivos juntos, tuve el problema de pérdida de memoria. De alguna manera, "include_once" no incluye las cosas una vez, o estoy haciendo algo mal ...
PHP 5.3+ le permite cambiar el límite de memoria colocando un archivo .user.ini
en la carpeta public_html
. Simplemente crea el archivo de arriba y escribe la siguiente línea en él:
memory_limit = 64M
Algunos hosts de cPanel solo aceptan este método.
Para aquellos que se están rascando el pelo para descubrir por qué en la tierra esta pequeña función debería causar una pérdida de memoria, a veces por un pequeño error, una función comienza a llamarse a sí misma de forma recursiva para siempre.
Por ejemplo, una clase de proxy que tiene el mismo nombre para una función del objeto que lo va a representar.
class Proxy {
private $actualObject;
public function doSomething() {
return $this->actualObjec->doSomething();
}
}
A veces, puede olvidarse de traer a ese pequeño miembro de realObjec y como el Proxy en realidad tiene ese método DoSomething, PHP no le daría ningún error y, para una clase numerosa, podría ocultarlo de los ojos durante un par de minutos para descubrir por qué Está perdiendo la memoria.
Para los usuarios de Drupal, esta respuesta de Chris Lane es:
ini_set(''memory_limit'', ''-1'');
Funciona pero hay que ponerlo justo después de la apertura.
<?php
etiqueta en el archivo index.php en el directorio raíz de tu sitio.
Puede corregir esto correctamente cambiando memory_limit en fastcgi / fpm
$vim /etc/php5/fpm/php.ini
Cambia la memoria como de 128 a 512 ver abajo
; Maximum amount of memory a script may consume (128MB)
; http://php.net/memory-limit
memory_limit = 128M
a
; Maximum amount of memory a script may consume (128MB)
; http://php.net/memory-limit
memory_limit = 512M
Seguí recibiendo este error, incluso con memory_limit
establecido en php.ini
, y el valor se lee correctamente con phpinfo()
.
Al cambiarlo de esto:
memory_limit=4G
A esto:
memory_limit=4096M
Esto rectificó el problema en PHP 7.
Si está ejecutando un VPS (Virtual Private Server) alimentado por WHM, es posible que no tenga permisos para editar PHP.INI directamente; El sistema debe hacerlo. En el panel de control de host de WHM, vaya a Configuración de servicio> Editor de configuración de PHP, modifique memory_limit:
Tuve el error a continuación mientras corría en un conjunto de datos más pequeño que el que había trabajado anteriormente.
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 4096 bytes) in C://workspace/image_management.php on line 173
Como la búsqueda de la falla me trajo aquí, pensé en mencionar que no siempre son las soluciones técnicas anteriores, sino algo más simple. En mi caso fue Firefox. Antes de ejecutar el programa ya estaba usando 1,157M.
Resulta que había estado viendo un video de 50 minutos un poco a la vez durante un período de días y eso arruinó las cosas. Es el tipo de solución que los expertos corrigen sin siquiera pensarlo, pero para mí, vale la pena tenerlo en cuenta.
ini_set(''memory_limit'', ''-1'');
anula el límite de memoria PHP predeterminado.
Directorio raíz de su sitio: -
ini_set(''memory_limit'', ''1024M'');
(Ocurre cuando MySQL tiene que consultar filas grandes, de manera predeterminada, momory_limit se establece en pequeño, lo que es más seguro para el hardware)
Puede verificar el estado de la memoria existente en su sistema, antes de aumentar php.ini
# free -m
total used free shared buffers cached
Mem: 64457 63791 666 0 1118 18273
-/+ buffers/cache: 44398 20058
Swap: 1021 0 1021
Aquí lo he aumentado como sigue y luego service httpd restart
para solucionar el problema de la página de CRASH.
# grep memory_limit /etc/php.ini
memory_limit = 512M