783 Stimmen

Schwerwiegender Fehler: Erlaubte Speichergröße von 134217728 Bytes erschöpft (CodeIgniter + XML-RPC)

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

Die Client-Kasse basiert auf PHPPOS, und ich habe ein Modul implementiert, das die Standard-XML-RPC-Bibliothek verwendet, um Verkaufsdaten an den Dienst 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 gehe davon aus, dass das eine große Zahl ist, die es zu knacken gilt. In der Tat habe ich sogar versucht, diesen Wert auf 1024M, und alles, was es tut, ist eine längere Zeit dauern, um Fehler aus.

Was die Schritte angeht, die ich unternommen habe, so habe ich versucht, alle Verarbeitungen auf der Serverseite zu deaktivieren, und ich habe es so eingerichtet, dass ich unabhängig von der Eingabe eine vorgefertigte Antwort erhalte. Ich glaube jedoch, dass das Problem in der tatsächlichen Übermittlung der Daten liegt. Ich habe sogar versucht, die maximale Skriptausführungszeit für PHP zu deaktivieren, und es tritt immer noch ein Fehler auf.

6 Stimmen

Ich bin etwas verwirrt... wo tritt der Fehler auf - im Client oder im Server? Und in welchem Stadium... Client sendet, Server empfängt, Server verarbeitet, Server sendet, Client empfängt oder Client verarbeitet?

0 Stimmen

Wie/wo setzen Sie das memory_limit auf 1024M?

3 Stimmen

Der Fehler scheint entweder beim Senden durch den Client oder beim Empfangen durch den Server aufzutreten. Ich habe versucht, die gesamte serverseitige Verarbeitung zu deaktivieren und den Server so einzustellen, dass er unabhängig von den gesendeten Daten eine Standardantwort sendet. Der Fehler tritt auf, wenn ich mehr als eine bestimmte Menge an Daten sende. Ich habe die PHP.ini-Einstellung geändert.

7voto

M61Vulcan Punkte 307

Bei der Ausführung eines kleineren Datensatzes als zuvor trat der folgende Fehler auf.

Fataler Fehler: Erlaubte Speichergröße von 134217728 Bytes erschöpft (versucht, 4096 Bytes zuzuweisen) in C:\workspace\image_management.php in Zeile 173

Da mich die Suche nach dem Fehler hierher geführt hat, dachte ich, ich sollte 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 startete, verbrauchte es bereits 1.157 MB.

Es stellte sich heraus, dass ich mir ein 50-minütiges Video über mehrere Tage hinweg nach und nach angeschaut hatte, und das brachte alles durcheinander. Es ist die Art von Fehler, die Experten korrigieren, ohne überhaupt darüber nachzudenken, aber für Leute wie mich ist es eine Überlegung wert.

0 Stimmen

Ich hatte heute einen ähnlichen Vorfall bei Google Chrome. Ich war äußerst skeptisch, was diese Antwort anging ... aber es zeigte sich, dass meine Byte-Erschöpfung verschwand, nachdem ich ein Inkognito-Fenster öffnete und dasselbe Skript erneut abfeuerte! Die Nachforschungen gehen weiter.

0 Stimmen

Für diejenigen, die nach Antworten suchen... würde ich das hier auslassen. Ich sehe keine Möglichkeit, dass der Speicherverbrauch eines Webbrowsers (wie Chrome oder Firefox) auf dem Client-Rechner irgendetwas mit dem Speicherverbrauch eines PHP-Skripts auf dem Server-Rechner zu tun hat. Wenn jemand bemerkt hat, dass ein Speicherproblem auf dem Server verschwindet, wenn sich etwas auf dem Client ändert, ist das ohne Frage ein Zufall. Das soll nicht heißen, dass eine Client-Anfrage für eine Menge Dinge dazu führen könnte, dass einem Server (mit schlechtem Code) der Speicher ausgeht oder dem Client (mit anderem schlechten Code) ebenfalls der Speicher ausgeht.

4voto

LukeDS Punkte 151

Verwendung von yield könnte ebenfalls eine Lösung sein. Siehe Generator-Syntax .

Anstatt die PHP.ini Datei für einen größeren Speicherplatz, manchmal wird eine yield innerhalb einer Schleife könnte das Problem beheben. Die Ausbeute besteht darin, dass nicht alle Daten auf einmal ausgegeben werden, sondern eine nach der anderen gelesen wird, wodurch viel Speicherplatz eingespart wird.

2 Stimmen

PHP.ini ? Ist es nicht php.ini ?

2voto

Kerim Punkte 1101

Ich finde es nützlich, wenn man Folgendes einbezieht oder verlangt _dbconnection.php_ y _functions.php in den Dateien, die tatsächlich verarbeitet werden, und nicht in der Kopfzeile. Dieser ist in sich selbst enthalten.

Wenn also Ihr Kopfzeile y Fußzeile enthalten ist, binden Sie einfach alle Ihre Funktionsdateien ein, bevor der Header eingebunden wird.

2voto

David Spector Punkte 1194

Die häufigste Ursache für diese Fehlermeldung ist für mich das Weglassen des "++"-Operators in einer PHP "for"-Anweisung. Dies führt dazu, dass die Schleife ewig weiterläuft, unabhängig davon, wie viel Speicher Sie verwenden dürfen. Es handelt sich um einen einfachen Syntaxfehler, der jedoch für den Compiler oder das Laufzeitsystem schwer zu erkennen ist. Für uns ist er leicht zu korrigieren, wenn wir daran denken, danach zu suchen!

Aber angenommen, Sie wollen ein allgemeines Verfahren, um eine solche Schleife vorzeitig zu beenden und den Fehler zu melden? Sie können einfach jede Ihrer Schleifen (oder zumindest die innersten Schleifen) wie unten beschrieben instrumentieren.

In einigen Fällen, z. B. bei Rekursionen innerhalb von Ausnahmen, set_time_limit fehlschlägt und der Browser weiterhin versucht, die PHP-Ausgabe zu laden, entweder in einer Endlosschleife oder mit der fatalen Fehlermeldung, die das Thema dieser Frage ist.

Wenn Sie die zulässige Zuweisungsgröße am Anfang Ihres Codes reduzieren, können Sie den fatalen Fehler möglicherweise verhindern, wie in den anderen Antworten beschrieben.

Dann kann es sein, dass das Programm zwar beendet wird, aber trotzdem schwer zu debuggen ist.

Unabhängig davon, ob Ihr Programm abbricht oder nicht, instrumentieren Sie Ihren Code durch Einfügen von BreakLoop() Aufrufe innerhalb Ihres Programms, um die Kontrolle zu übernehmen 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 (!@$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 Argument $LoopSite kann der Name einer Funktion in Ihrem Code sein. Es ist nicht wirklich notwendig, da die Fehlermeldung, die Sie erhalten, Sie auf die Zeile verweist, die den BreakLoop()-Aufruf enthält.

2voto

ratm Punkte 895

Führen Sie das Skript wie folgt aus (z. B. im Cron-Fall): php5 /pathToScript/info.php führt zu demselben Fehler.

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X