Error fatal: tamaño de memoria permitido de 134217728 bytes agotados (CodeIgniter + XML-RPC)

Tengo un montón de sistemas de punto de venta (POS) de clientes 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 POS del cliente se basa en PHPPOS, y he implementado un módulo que usa la biblioteca estándar 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 una gran cantidad de datos de ventas (tan solo 50 filas de la tabla de ventas y filas individuales de sales_items correspondientes a cada artículo dentro de la venta), aparece 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 del error.

En cuanto a los pasos que he tomado, he intentado deshabilitar todo el procesamiento en el lado del servidor y lo he manipulado para devolver una respuesta predefinida 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 del script para PHP, y todavía aparecen errores.

preguntado el 18 de febrero de 09 a las 11:02

Estoy un poco confundido ... ¿dónde ocurre el error, en el cliente o en el servidor? ¿Y en qué etapa ... envío del cliente, recepción del servidor, procesamiento del servidor, envío del servidor, recepción del cliente o procesamiento del cliente? -

El error parece ocurrir durante el envío del cliente o durante la recepción del servidor. Intenté deshabilitar todo el procesamiento del lado del servidor y manipularlo para enviar una respuesta almacenada independientemente de los datos enviados. El error ocurre si envío una cierta cantidad de datos. Estoy cambiando la configuración de PHP.ini. -

el límite de memoria es de 128 MB, duplícalo: ini_set('memory_limit', '256M'); -

Resumen rechazó todas las respuestas "simplemente ignore la filtración", las personas que confundieron CodeIgniter con Drupal y las personas que simplemente copiaron y pegaron las respuestas de otras personas para obtener puntos. La calidad de las respuestas en este es abismal. -

30 Respuestas

Cambiando el memory_limit by ini_set('memory_limit', '-1'); is no una solución adecuada. Por favor, no hagas eso.

Su código PHP puede tener una pérdida de memoria en alguna parte y le está diciendo al servidor que use toda la memoria que quiera. No habrías solucionado el problema en absoluto. Si supervisa su servidor, verá que ahora probablemente esté consumiendo la mayor parte de la RAM e incluso cambiando al disco.

Probablemente debería intentar rastrear el código ofensivo en su código y solucionarlo.

contestado el 12 de mayo de 18 a las 05:05

@Jeff, probablemente tengas razón el 95% del tiempo. Sin embargo, hay ocasiones en las que realmente necesita más memoria. Por ejemplo, digamos que su aplicación está cargando una gran cantidad de datos en la memoria para su procesamiento (digamos una lista de materiales con 15k componentes). No siempre es el caso de que el código tenga errores, a veces solo necesitas un poco más de memoria (por ejemplo, 256 M en lugar de 128 M). Sin embargo, estoy de acuerdo en que establecerlo en -1 es terriblemente malo. Pero ajustar el límite de memoria para situaciones razonables en tiempo de ejecución es perfectamente aceptable en mi humilde opinión. - Pirita

@pyrite, sí, tiene razón en que a veces un proceso requiere más memoria, pero debe aumentar el límite de memoria a una cantidad lógica como 256 MB como dijo o 512 MB, ¿por qué no PERO no -1;) - Lukas Lukac

@jeff Estoy totalmente de acuerdo, un valor de -1 Podría ser útil , solamente en entornos de desarrollo para propósitos de prueba. - Esolitos

@Pyrite en los casos que nombró para el 5% restante, lea los datos en trozos y use un trabajador para procesarlos en lugar de usar más memoria. Esta solución también se ampliará, mientras que su sugerencia no funcionará, excepto que siga almacenando más y más memoria en su servidor a lo largo del tiempo si los datos aumentan. - burzum

De la manera más común, este problema en ORM cuando intenta obtener todos los datos que tienen mucho más límite de memoria php. Por ejemplo, cuando intenta generar un informe mensual. - Stepchik

ini_set('memory_limit', '-1'); anula el predeterminado Límite de memoria PHP.

respondido 01 nov., 11:10

@williamcarswell; -1 es un valor que PHP entiende como ilimitado en este contexto. - Alix Axel

@ ArseniuszŁozicki - también consumirá recursos del servidor no puedes repuesto. - Ken Williams

Es una pena que esto reciba tantos votos a favor. Establecerlo en un valor preciso, ya sea con php.ini ediciones o ini_set, es una solución perfectamente válida cuando las personas necesitan más memoria. Establecerlo en ilimitado es un truco peligroso :( - Jeff Davis

@ user1767586 luego configúrelo en un valor sensato. Puede evitar que el script arroje el error configurándolo en 1024M. Si esta respuesta dice ini_set ('memory_limit', '1024M'); Podrías copiar y pegar eso y estarás bien. Al establecerlo en -1, se está configurando para tener un script que consume toda la memoria. Especialmente si haces esto de forma rutinaria. Poner "peligroso" entre comillas no lo hace menos peligroso. Realmente podría limpiar su servidor host. Quizás empiece a destruir datos. No lo sé, ¿quizás pierdas tu trabajo? Me suena bastante peligroso. : | - Jeff Davis

Es triste ver que la respuesta para +161 votos y -3 votos es la misma :( - akarthik10

La forma correcta es editar su php.ini expediente. Editar memory_limit a su valor de deseo.

A partir de tu pregunta, 128M (que es el límite predeterminado) se ha excedido, por lo que hay algo muy mal con su código, ya que no debería tomar tanto.

Si sabe por qué se necesita tanto y desea permitir que se establezca memory_limit = 512M o superior y deberías ser bueno.

Respondido el 09 de diciembre de 13 a las 09:12

Honestamente, si almacena en caché una gran cantidad de datos, esta es la respuesta correcta. 128M no es suficiente para ciertos scripts. 512M o 1024M a menudo serán suficientes, pero debe decidir caso por caso. - Jeff Davis

Sí, sin embargo, trate de evitar un uso excesivo de la memoria, si la cantidad de usuarios va a ser mayor. Basav

límite_memoria = -1; establecido en php.ini - user285594

@YumYumYum Eso elimina el memory_limit, que solo desea si está monitoreando el uso de la memoria de alguna otra manera. El sistema operativo matará el proceso si está ocupando una gran cantidad de memoria en algún momento. - flim

Entonces, si está ejecutando un script que usa mucha memoria, pero solo necesita ejecutarlo una vez, ¿puede simplemente aumentar el límite de memoria para el proceso en el momento de la ejecución, luego reducir su límite de memoria nuevamente después de su única vez ¿Se ejecuta el script? - cromecris

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 formas.

Si tiene acceso a su php.ini archivo, puede editar el valor de memory_limit a su valor de deseo.

Si no tiene acceso a su php.ini archivo (y su servidor web lo permite), puede anular la asignación de memoria a través de su .htaccess expediente. Agregar 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 tienes el código ini_set('memory_limit', '128M'); (o cualquiera que sea su asignación deseada). Puede eliminar el límite de memoria (aunque los límites de la máquina o la instancia aún pueden aplicarse) estableciendo el valor en "-1".

contestado el 12 de mayo de 15 a las 14:05

Gracias, no pensé en verificar si alguien había establecido el valor en .htaccess que estaba anulando php.ini y no pude entender por qué +1 - HostMyBus

Para cualquier persona que necesite configurar temporalmente con comandos: php -d memory_limit=256M your_php_file.php or php -d memory_limit=256M artisan ... - El Anh Nguyen

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 perfilar su secuencia de comandos y descubra dónde se fue toda esa memoria.

Respondido 18 Feb 09, 14:02

Iré a probar Xdebug. Nunca lo había usado antes, así que tendré que leerlo. ¡Gracias por responder! Espero encontrar la respuesta a esto pronto ... - ArcticZero

Recuerde que PHP usa el recuento de referencias para administrar la memoria. Entonces, si tiene referencias circulares o variables globales, esos objetos no se reciclarán. Esa suele ser la raíz de las pérdidas de memoria en PHP. - troelskn

Xdebug muestra que la biblioteca Xmlrpc.php de CI es responsable de mi pérdida de memoria. Por casualidad, ¿habría algún problema con las bibliotecas XML-RPC de CodeIgniter que debería conocer? Intenté deshabilitar todo el procesamiento del lado del servidor, y todavía se queda sin memoria si le doy suficientes datos. - ArcticZero

No sé / uso CI, así que no lo sé. Pero probablemente debería intentar encontrar un objeto que no se libere después de su uso, probablemente debido a una referencia cíclica. Es trabajo de detective. - troelskn

Esta es la única respuesta aquí que aconseja abordar realmente el problema. Las otras respuestas aumentan la memoria para vendar un síntoma e ignorar el enfermedades. - Chris Baker

Al agregar 22.5 millones de registros en una matriz con array_push, seguía obteniendo errores fatales de "memoria agotada" en alrededor de 20 millones de registros usando 4G como límite de memoria en el archivo php.ini. Para solucionar 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 sencillo:

$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.

Respondido 24 Jul 19, 22:07

Quiere decir ini_set('memory_limit', '8192M'); ? - Gogol

Qué lujo sería tener tiempo para optimizar un script para algo así. O investigue, compare y aprenda herramientas ETL o algo por el estilo. En el mundo real, aumentamos la asignación de memoria, hacemos las cosas y seguimos adelante. - mateo poer

Seguí recibiendo este error, incluso con memory_limit establecer en php.ini, y el valor se lee correctamente con phpinfo().

Cambiándolo de esto:

memory_limit=4G

A esto:

memory_limit=4096M

Esto rectificó el problema en PHP 7.

Respondido el 26 de enero de 18 a las 23:01

Cuando vea el error anterior, especialmente si el (tried to allocate __ bytes) es un valor bajo, que 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();
}

contestado el 08 de mayo de 15 a las 21:05

El directorio raíz de su sitio:

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

Respondido 24 Jul 19, 22:07

esto funcionó para mí. Me encantan las soluciones de una línea. +1 por simplicidad - Steve C

Puede solucionar esto correctamente cambiando memory_limit en fastcgi / fpm:

$vim /etc/php5/fpm/php.ini

Cambie la memoria, como de 128 a 512, vea a continuación

; Maximum amount of memory a script may consume (128 MB)
; http://php.net/memory-limit
memory_limit = 128M

a

; Maximum amount of memory a script may consume (128 MB)
; http://php.net/memory-limit
memory_limit = 512M

Respondido 24 Jul 19, 22:07

Después de habilitar estas dos líneas, comenzó a funcionar:

; 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

Respondido 24 Jul 19, 22:07

En Drupal 7, puede modificar el límite de memoria en el archivo settings.php ubicado en sus sitios / carpeta 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á configurado en su archivo Drupal settings.php.

Respondido 24 Jul 19, 22:07

No en Drupal7 no existe tal cadena de código en settings.php - FLY

Tampoco hay una cadena en settings.php para drupal 6 - allisonc

Cambiar el límite de memoria en el php.ini archivo y reinicie Apache. Después del reinicio, ejecute el phpinfo (); función desde cualquier archivo PHP para un memory_limit confirmación de cambio.

memory_limit = -1

El límite de memoria -1 significa que no hay ningún límite de memoria establecido. Ahora está al máximo.

Respondido 24 Jul 19, 23:07

Para los usuarios de Drupal, esta respuesta de Chris Lane de:

ini_set('memory_limit', '-1');

funciona pero tenemos que ponerlo justo después de la apertura

<?php

etiqueta en el archivo index.php en el directorio raíz de su sitio.

Respondido el 06 de diciembre de 12 a las 17:12

En lugar de cambiar el memory_limit valor en tu php.ini archivo, si hay una parte de su código que podría usar mucha memoria, puede eliminar el memory_limit antes de que se ejecute esa sección, y luego reemplácela después.

$limit = ini_get('memory_limit');
ini_set('memory_limit', -1);
// ... do heavy stuff
ini_set('memory_limit', $limit);

Respondido 07 Feb 18, 12:02

Sólo agrega un ini_set('memory_limit', '-1'); línea en la parte superior de su página web.

Y puede configurar su memoria según su necesidad en el lugar de -1, para 16MEtc. ..

Respondido 24 Jul 19, 23:07

Esto parece decir lo mismo que muchas respuestas existentes. Es mejor agregar una respuesta a una pregunta popular solo si el nuevo material ofrece algo novedoso. - la mitad

PHP 5.3+ le permite cambiar el límite de memoria colocando un .user.ini presentar en el public_html carpeta. Simplemente cree el archivo anterior y escriba la siguiente línea en él:

memory_limit = 64M

Algunos hosts de cPanel solo aceptan este método.

Respondido 28 Jul 14, 11:07

¿Página de bloqueo?

Ingrese la descripción de la imagen aquí

(Ocurre cuando MySQL tiene que consultar filas grandes. De forma predeterminada, memory_limit está configurado en pequeño, que era más seguro para el hardware).

Puede verificar el estado de la memoria existente de 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 en el siguiente y luego hago service httpd restart para solucionar el problema de la página de bloqueo.

# grep memory_limit /etc/php.ini
memory_limit = 512M

Respondido 24 Jul 19, 22:07

¿Qué número (fila y columna?) Se debe mirar después de ejecutar el free -m comando para decidir sobre un nuevo memory_limit? - kiradotee

Para aquellos que se están rascando la cabeza para descubrir por qué diablos esta pequeña función debería causar una pérdida de memoria, a veces por un pequeño error, una función comienza recursivamente a llamarse a sí misma para siempre.

Por ejemplo, una clase de proxy que tiene el mismo nombre para una función del objeto que lo va a usar como proxy.

class Proxy {

    private $actualObject;

    public function doSomething() {

        return $this->actualObjec->doSomething();
    }
}

A veces puede olvidarse de traer ese pequeño miembro actual deObjec y porque el proxy realmente tiene eso doSomething , PHP no le daría ningún error y para una clase grande, podría estar oculto a los ojos durante un par de minutos para averiguar por qué está perdiendo la memoria.

Respondido 24 Jul 19, 22:07

Y otro consejo: puedes poner die('here') en su código y mueva esa declaración para ver dónde comienza la recursividad. - Toddmo

Tuve el siguiente error mientras corría en un conjunto de datos más pequeño que el que había funcionado anteriormente.

Error fatal: se agotó el tamaño de memoria permitido de 134217728 bytes (se intentó asignar 4096 bytes) en C: \ workspace \ image_management.php en la línea 173

Como la búsqueda de la falla me trajo aquí, pensé en mencionar que no siempre son las soluciones técnicas en las respuestas anteriores, sino algo más simple. En mi caso fue Firefox. Antes de ejecutar el programa, ya estaba usando 1,157 MB.

Resulta que había estado viendo un video de 50 minutos poco a poco durante un período de días y eso arruinó las cosas. Es el tipo de solución que los expertos corrigen sin siquiera pensar en ello, pero para personas como yo, vale la pena tenerlo en cuenta.

Respondido 24 Jul 19, 23:07

Hoy tuve una ocurrencia similar en Google Chrome. Era extremadamente escéptico con esta respuesta ... sin embargo, ¡reveló que mi agotamiento de bytes desapareció después de que abrí una ventana de incógnito y volví a disparar el mismo script! La investigación continúa. - mickmackusa

Usar yield también podría ser una solución. Ver Sintaxis del generador.

En lugar de cambiar el PHP.ini archivo para un mayor almacenamiento de memoria, a veces implementando un yield dentro de un bucle podría solucionar el problema. Lo que hace el rendimiento es que, en lugar de volcar todos los datos a la vez, los lee uno por uno, lo que ahorra mucho uso de memoria.

Respondido 24 Jul 19, 23:07

PHP.ini? No es php.ini? - Pedro Mortensen

Ejecutando el script como este (caso cron, por ejemplo): php5 /pathToScript/info.php produce el mismo error.

La forma correcta: php5 -cli /pathToScript/info.php

respondido 16 nov., 16:03

Si está ejecutando un VPS (servidor privado virtual) con tecnología WHM, es posible que no tenga permisos para editar PHP.INI directamente; el sistema debe hacerlo. En el panel de control del host de WHM, vaya a Configuración del servicioEditor de configuración PHP y modificar memory_limit:

Actualización de memory_limit en WHM 11.48.4

Respondido 24 Jul 19, 22:07

Lo encuentro útil a la hora de incluir o requerir _dbconnection.php_ y _functions.php en archivos que se procesan realmente, en lugar de incluirlos en el encabezado. Que está incluido en sí mismo.

Entonces si tu encabezamiento y pie de página está incluido, simplemente incluya todos sus archivos funcionales antes de que se incluya el encabezado.

Respondido 24 Jul 19, 22:07

La causa más común de este mensaje de error para mí es omitir el operador "++" de una declaración PHP "for". Esto hace que el ciclo continúe para siempre, sin importar cuánta memoria permita que se use. Es un simple error de sintaxis, pero es difícil de detectar para el compilador o el sistema de tiempo de ejecución. ¡Es fácil para nosotros corregirlo si pensamos buscarlo!

Pero suponga que desea un procedimiento general para detener un ciclo de este tipo antes de tiempo y reportar el error. Simplemente puede instrumentar cada uno de sus bucles (o al menos los bucles más internos) como se explica a continuación.

En algunos casos, como la recursividad dentro de excepciones, set_time_limit falla, y el navegador sigue intentando cargar la salida de PHP, ya sea con un bucle infinito o con el mensaje de error fatal que es el tema de esta pregunta.

Al reducir el tamaño de asignación permitido cerca del comienzo de su código, es posible que pueda evitar el error fatal, como se explica en las otras respuestas.

Entonces es posible que se quede con un programa que finaliza, pero que aún es difícil de depurar.

Ya sea que su programa finalice o no, instrumente su código insertando BreakLoop() llamadas dentro de su programa para obtener el control y averiguar qué bucle o recursividad en su programa está causando el problema.

La definición de BreakLoop es la siguiente:

function BreakLoop($MaxRepetitions=500,$LoopSite="unspecified")
    {
    static $Sites=[];
    if (!@$Sites[$LoopSite] || !$MaxRepetitions)
        $Sites[$LoopSite]=['n'=>0, 'if'=>0];
    if (!$MaxRepetitions)
        return;
    if (++$Sites[$LoopSite]['n'] >= $MaxRepetitions)
        {
        $S=debug_backtrace(); // array_reverse
        $info=$S[0];
        $File=$info['file'];
        $Line=$info['line'];
        exit("*** Loop for site $LoopSite was interrupted after $MaxRepetitions repetitions. In file $File at line $Line.");
        }
    } // BreakLoop

El argumento $ LoopSite puede ser el nombre de una función en su código. No es realmente necesario, ya que el mensaje de error que recibirá le indicará la línea que contiene la llamada BreakLoop ().

Respondido el 23 de junio de 20 a las 17:06

En mi caso, fue un problema breve con la forma en que se escribió una función. Se puede producir una pérdida de memoria al asignar un nuevo valor a la variable de entrada de una función, por ejemplo:

/**
* Memory leak function that illustrates unintentional bad code
* @param $variable - input function that will be assigned a new value
* @return null
**/
function doSomehting($variable){
    $variable = 'set value';
    // Or
    $variable .= 'set value';
}

Respondido 24 Jul 19, 23:07

cambiar ;memory_limit=512M a ;memory_limit=-1 in enter image description here

es demasiado peligroso para un servidor Su código PHP puede tener una fuga de memoria en alguna parte y le está diciendo al servidor que use toda la memoria que quiera. No habrías solucionado el problema en absoluto. Si supervisa su servidor, verá que ahora probablemente esté consumiendo la mayor parte de la RAM e incluso cambiando al disco.

Respondido el 13 de Septiembre de 20 a las 09:09

Pasé dos días buscando una solución para esto y descubrí que esto era una causa en una llamada con PDO cuando llamé

$stmt->bindParam(":PERIOD", $period); 

y el período de variables fue un

empty string ''

Por lo tanto, este problema podría tener una causa raíz múltiple, mi consejo es que intente un método de prueba y error o un método de bisección para encontrar la causa raíz, elimine el código e intente buscar cuál es el código de línea que está fallando

Actualización: también enfrenté este error con el método $ pdo-> query () Usé $ pdo-> prepare () y funcionó bien, así que, mientras tenía

$sql = "SELECT * FROM COURSE_DETAILS where ACTIVE = 1 AND COURSE_DETAILS_ID = $id";
$stmt = getConnection()->query($sql);
$courseDetails = $stmt->fetchAll(PDO::FETCH_ASSOC)

luego cambié esto a

$sql = "SELECT * FROM COURSE_DETAILS where ACTIVE = 1 AND COURSE_DETAILS_ID = ?";
$stmt = getConnection()->prepare($sql);
$stmt->execute(array($id)); 

¡y mágicamente desapareció el error de memoria!

respondido 11 nov., 20:03

En mi caso en mac (Catalina - Xampp) no había ningún archivo cargado, así que tuve que hacer esto primero.

sudo cp /etc/php.ini.default /etc/php.ini
sudo nano /etc/php.ini

Entonces cambia memory_limit = 512M

Luego reinicie Apache y verifique si el archivo está cargado

php -i | grep php.ini

El resultado fue

Configuration File (php.ini) Path => /etc
Loaded Configuration File => /etc/php.ini

Finalmente comprobar

php -r "echo ini_get('memory_limit').PHP_EOL;"

Respondido el 21 de enero de 21 a las 00:01

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 estaba ejecutando. Al ejecutar los archivos uno por uno, todos funcionaron bien, pero al ejecutar todos los archivos juntos tuve el problema de pérdida de memoria. De alguna manera, "include_once" no incluye cosas una vez, o estoy haciendo algo mal ...

Respondido 24 Jul 19, 22:07

set_include_path(get_include_path() . get_include_path().'/phpseclib'); Esto agregará la ruta '/ phpseclib' una vez para cada archivo que tenga la línea ... ¡para que pueda agregarla muchas veces! Sugeriría ponerlo en un archivo de configuración y include_once el archivo de configuración. - Lejos de único

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.