it-swarm.com.de

Schwerwiegender Fehler: Zulässige Speichergröße von 134217728 Byte erschöpft (CodeIgniter + XML-RPC)

Ich habe eine Reihe von POS-Systemen (Client Point of Sale), die regelmäßig neue Verkaufsdaten an eine zentrale Datenbank senden, in der die Daten zur Berichterstellung in einer großen Datenbank gespeichert werden.

Der Client-POS basiert auf PHPPOS, und ich habe ein Modul implementiert, das die Standard-XML-RPC-Bibliothek verwendet, um Verkaufsdaten an den Service zu senden. Das Serversystem basiert auf CodeIgniter und verwendet die XML-RPC- und XML-RPCS-Bibliotheken für die Webservice-Komponente. Immer wenn ich viele Verkaufsdaten sende (nur 50 Zeilen aus der Verkaufstabelle und einzelne Zeilen aus sales_items, die sich auf jeden Artikel innerhalb des Verkaufs beziehen), erhalte ich den folgenden Fehler:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 54 bytes)

128M ist der Standardwert in php.ini, aber ich nehme an, das ist eine riesige Zahl, die es zu knacken gilt. Tatsächlich habe ich sogar versucht, diesen Wert auf 1024 M zu setzen, und es dauert nur eine längere Zeit, bis ein Fehler auftritt.

Bei den von mir ausgeführten Schritten habe ich versucht, die gesamte Verarbeitung auf der Serverseite zu deaktivieren, und habe sie so manipuliert, dass sie unabhängig von der Eingabe eine vorgefertigte Antwort zurückgibt. Ich glaube jedoch, dass das Problem im tatsächlichen Senden der Daten liegt. Ich habe sogar versucht, die maximale Skriptausführungszeit für PHP zu deaktivieren, und es treten weiterhin Fehler auf.

576
ArcticZero

Das Ändern des memory_limit durch ini_set('memory_limit', '-1'); ist nicht eine richtige Lösung. Bitte tu das nicht.

Ihr PHP Code hat möglicherweise irgendwo einen Speicherverlust und Sie weisen den Server an, nur den gesamten gewünschten Speicher zu verwenden. Sie hätten das Problem überhaupt nicht behoben. Wenn Sie Ihren Server überwachen, werden Sie feststellen, dass er jetzt wahrscheinlich den größten Teil des RAM verbraucht und sogar auf die Festplatte wechselt.

Sie sollten wahrscheinlich versuchen, den fehlerhaften Code in Ihrem Code aufzuspüren und zu beheben.

675
Jeff

ini_set('memory_limit', '-1'); überschreibt die Standardeinstellung PHP-Speicherbeschränkung .

205
Chris Lane

Der richtige Weg ist, Ihre php.ini -Datei zu bearbeiten. Bearbeiten Sie memory_limit zu Ihrem Wunschwert.

Wie aus Ihrer Frage hervorgeht, wurde 128M (dies ist das Standardlimit) überschritten, sodass ein schwerwiegender Fehler in Ihrem Code vorliegt, da dieser nicht so viel dauern sollte.

Wenn Sie wissen, warum es so viel kostet, und wenn Sie zulassen möchten, dass es memory_limit = 512M oder höher setzt, sollten Sie gut sein.

124
Basav

Die Speicherzuordnung für PHP kann permanent oder temporär angepasst werden.

Permanent

Sie können die PHP Speicherzuordnung auf zwei Arten dauerhaft ändern.

Wenn Sie Zugriff auf Ihre php.ini -Datei haben, können Sie den Wert für memory_limit auf Ihren Wunschwert ändern.

Wenn Sie keinen Zugriff auf Ihre php.ini -Datei haben (und Ihr Webhost dies zulässt), können Sie die Speicherzuordnung über Ihre .htaccess -Datei überschreiben. Fügen Sie php_value memory_limit 128M hinzu (oder was auch immer Ihre gewünschte Zuordnung ist).

Befristet

Sie können die Speicherzuordnung direkt in einer PHP -Datei anpassen. Sie haben einfach den Code ini_set('memory_limit', '128M'); (oder was auch immer Ihre gewünschte Zuordnung ist). Sie können das Speicherlimit aufheben (obwohl möglicherweise noch Computer- oder Instanzlimits gelten), indem Sie den Wert auf "-1" setzen.

93
Umair Idrees

Es ist sehr einfach, Speicherlecks in einem PHP -Skript zu finden - insbesondere, wenn Sie eine Abstraktion verwenden, z. B. ein ORM. Verwenden Sie Xdebug, um Ihr Skript zu profilieren und herauszufinden, wo sich der gesamte Speicher befindet.

59
troelskn

Beim Hinzufügen von 22,5 Millionen Datensätzen zu einem Array mit array_Push kam es bei etwa 20 Millionen Datensätzen immer wieder zu schwerwiegenden Fehlern, bei denen 4G als Speicherbegrenzung in der Datei php.ini verwendet wurde. Um dies zu beheben, habe ich die Anweisung hinzugefügt

$old = ini_set('memory_limit', '8192M');

am Anfang der Datei. Jetzt funktioniert alles gut. Ich weiß nicht, ob PHP einen Speicherverlust hat. Das ist nicht mein Job, und es interessiert mich auch nicht. Ich muss nur meine Arbeit erledigen, und das hat funktioniert.

Das Programm ist sehr einfach:

$fh = fopen($myfile);
while (!feof($fh)) {
    array_Push($file, stripslashes(fgets($fh)));
}
fclose($fh);

Der schwerwiegende Fehler zeigt auf Zeile 3, bis ich das Speicherlimit erhöht habe, wodurch der Fehler behoben wurde.

51
JamesAD-0

Ich habe immer wieder diese Fehlermeldung erhalten, auch wenn memory_limit in php.ini eingestellt war und der Wert mit phpinfo() korrekt ausgelesen wurde.

Indem Sie dies ändern:

memory_limit=4G

Dazu:

memory_limit=4096M

Dies behebt das Problem in PHP 7.

45
Danny Beckett

Wenn Sie den obigen Fehler sehen - insbesondere wenn (tried to allocate __ bytes) ein niedriger Wert ist, könnte dies ein Indikator für eine Endlosschleife sein, wie eine Funktion, die sich selbst ohne Ausweg aufruft:

function exhaustYourBytes()
{
    return exhaustYourBytes();
}
22
Kristen Waite

Sie können dieses Problem beheben, indem Sie memory_limit auf fastcgi/fpm ändern:

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

Ändern Sie den Speicher, z. B. von 128 auf 512, siehe unten

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

zu

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

Nach dem Aktivieren dieser beiden Zeilen hat es funktioniert:

; 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

18

Das Stammverzeichnis Ihrer Website:

ini_set('memory_limit', '1024M');
14
Gaurang P

Für Drupal Benutzer lautet die Antwort von Chris Lane wie folgt:

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

funktioniert, aber wir müssen es kurz nach der Eröffnung setzen

<?php

tag in der index.php-Datei im Stammverzeichnis Ihrer Site.

12
sigmapi13

Anstatt den memory_limit -Wert in Ihrer php.ini -Datei zu ändern, können Sie den memory_limit entfernen, bevor dieser Abschnitt ausgeführt wird Ersetzen Sie es danach.

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

In Drupal 7 können Sie das Speicherlimit in der settings.php-Datei ändern, die sich in Ihrem sites/default-Ordner befindet. Um die Linie 260 sehen Sie Folgendes:

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

Selbst wenn Ihre php.ini-Einstellungen hoch genug sind, können Sie nicht mehr als 128 MB verbrauchen, wenn dies nicht in Ihrer Drupal settings.php-Datei festgelegt ist.

11
LK7889

Ändern Sie das Speicherlimit in der Datei php.ini und starten Sie Apache neu. Führen Sie nach dem Neustart die Funktion phpinfo (); in einer beliebigen PHP Datei aus, um eine memory_limit Änderungsbestätigung zu erhalten.

memory_limit = -1

Speicherlimit -1 bedeutet, dass kein Speicherlimit festgelegt wurde. Es ist jetzt am Maximum.

11
Hasib Kamal

Absturzseite?

Enter image description here

(Es passiert, wenn MySQL große Zeilen abfragen muss. Standardmäßig ist memory_limit auf small gesetzt, was für die Hardware sicherer war.)

Sie können den vorhandenen Speicherstatus Ihres Systems überprüfen, bevor Sie php.ini erhöhen:

# free -m
             total       used       free     shared    buffers     cached
Mem:         64457      63791        666          0       1118      18273
-/+ buffers/cache:      44398      20058
Swap:         1021          0       1021

Hier habe ich es wie folgt erhöht und dann service httpd restart ausgeführt, um das Absturzseitenproblem zu beheben.

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

Mit PHP 5.3+ können Sie das Speicherlimit ändern, indem Sie eine .user.ini -Datei in den public_html -Ordner legen. Erstellen Sie einfach die obige Datei und geben Sie die folgende Zeile ein:

memory_limit = 64M

Einige cPanel-Hosts akzeptieren nur diese Methode.

7
Sabi

Für diejenigen, die sich am Kopf kratzen, um herauszufinden, warum diese kleine Funktion zu einem Speicherverlust führen sollte, manchmal aus Versehen, ruft sich eine Funktion rekursiv für immer auf.

Beispiel: Eine Proxy-Klasse mit demselben Namen für eine Funktion des Objekts, das die Proxy-Funktion ausführen soll.

class Proxy {

    private $actualObject;

    public function doSomething() {

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

Manchmal vergisst du vielleicht, das kleine Mitglied actualObjec mitzubringen, und da der Proxy tatsächlich diese doSomething -Methode hat, würde PHP dir keinen Fehler machen, und für eine große Klasse könnte sie vor der verborgen werden Augen für ein paar Minuten, um herauszufinden, warum es die Erinnerung verliert.

6
madz

Ich hatte den folgenden Fehler, als ich auf einem kleineren Datensatz lief, als zuvor funktioniert hatte.

Schwerwiegender Fehler: Die zulässige Speichergröße von 134217728 Byte ist erschöpft (es wurde versucht, 4096 Byte zuzuweisen) in C:\workspace\image_management.php in Zeile 173

Als die Suche nach dem Fehler mich hierher brachte, dachte ich, ich würde erwähnen, dass es nicht immer die technischen Lösungen in früheren Antworten sind, sondern etwas einfacheres. In meinem Fall war es Firefox. Bevor ich das Programm ausführte, verwendete es bereits 1.157 MB.

Es stellte sich heraus, dass ich über einen Zeitraum von Tagen hinweg jeweils ein 50-minütiges Video angeschaut hatte, und das hat alles durcheinander gebracht. Es ist die Art von Korrektur, die Experten korrigieren, ohne darüber nachzudenken, aber für mich ist es wert, daran zu denken.

4
M61Vulcan

Wenn Sie einen WHM-basierten VPS (Virtual Private Server) verwenden, haben Sie möglicherweise keine Berechtigung, PHP.INI direkt zu bearbeiten. Das System muss es tun. Gehen Sie im WHM Host Control Panel zu Service ConfigurationPHP Configuration Editor und ändern Sie memory_limit:

Updating memory_limit on WHM 11.48.4

2
Janckos

Wenn Sie das Skript folgendermaßen ausführen (z. B. in Groß- und Kleinschreibung): php5 /pathToScript/info.php wird der gleiche Fehler ausgegeben.

Der richtige Weg: php5 -cli /pathToScript/info.php

2
ratm

Ich finde es nützlich, wenn ich _dbconnection.php_ und _functions.php in Dateien einbinde oder benötige, die tatsächlich verarbeitet werden, anstatt sie in den Header aufzunehmen. Welches ist in sich selbst enthalten.

Wenn also Ihre Kopfzeile und Fußzeile enthalten sind, schließen Sie einfach alle Ihre Funktionsdateien ein, bevor die Kopfzeile enthalten ist.

2
Kerim

Dieser Fehler wird manchmal durch einen Fehler im Code PHP verursacht, der zu Rekursionen mit Ausnahmebehandlung und möglicherweise anderen Vorgängen führt. Leider konnte ich kein kleines Beispiel erstellen.

In diesen Fällen, die bei mir mehrmals vorgekommen sind, schlägt set_time_limit fehl und der Browser versucht weiterhin, die PHP - Ausgabe zu laden, entweder mit einer Endlosschleife oder mit der schwerwiegenden Fehlermeldung Thema dieser Frage.

Durch Verringern der zulässigen Zuordnungsgröße durch Hinzufügen

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

kurz vor dem Beginn Ihres Codes sollten Sie in der Lage sein, den schwerwiegenden Fehler zu verhindern.

Dann kann es sein, dass Sie ein Programm haben, das beendet wird, aber immer noch schwer zu debuggen ist.

An dieser Stelle fügen Sie BreakLoop() Aufrufe in Ihr Programm ein, um die Kontrolle zu erlangen und herauszufinden, welche Schleife oder Rekursion in Ihrem Programm das Problem verursacht.

Die Definition von BreakLoop lautet wie folgt:

function BreakLoop($MaxRepetitions=500,$LoopSite="unspecified")
    {
    static $Sites=[];
    if ([email protected]$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

Das $ LoopSite-Argument kann der Name einer Funktion in Ihrem Code sein. Dies ist nicht unbedingt erforderlich, da Sie in der Fehlermeldung auf die Zeile mit dem BreakLoop () -Aufruf hingewiesen werden.

1
David Spector

Die Verwendung von yield könnte ebenfalls eine Lösung sein. Siehe Generatorsyntax.

Anstatt die PHP.ini -Datei für einen größeren Speicher zu ändern, kann das Problem durch Implementieren von yield in einer Schleife behoben werden. Statt alle Daten auf einmal zu sichern, werden sie einzeln gelesen, wodurch viel Speicherplatz gespart wird.

0
LukeDS

In meinem Fall war es ein kurzes Problem mit der Art und Weise, wie eine Funktion geschrieben wurde. Ein Speicherverlust kann verursacht werden, indem der Eingangsvariablen einer Funktion ein neuer Wert zugewiesen wird, z.

/**
* 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';
}
0

Fügen Sie einfach ini_set ('memory_limit', '-1') hinzu. Zeile oben auf Ihrer Webseite. Und Sie können Ihren Speicher je nach Bedarf auf einen Wert zwischen -1 und 16 MB usw. einstellen.

0