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 die folgende Fehlermeldung:
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 dies eine große Zahl ist, die gebrochen werden muss. Tatsächlich habe ich sogar versucht, diesen Wert auf 1024 MB einzustellen, und es dauert nur länger, bis ein Fehler auftritt.
Bei den von mir unternommenen Schritten habe ich versucht, die gesamte Verarbeitung auf der Serverseite zu deaktivieren, und sie so manipuliert, dass unabhängig von der Eingabe eine vordefinierte Antwort zurückgegeben wird. 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 immer noch Fehler auf.
quelle
ini_set('memory_limit', '256M');
Antworten:
Das Ändern
memory_limit
vonini_set('memory_limit', '-1');
ist nicht eine richtige Lösung. Bitte tu das nicht.Ihr PHP-Code weist möglicherweise irgendwo einen Speicherverlust auf 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 Arbeitsspeichers belegt und sogar auf die Festplatte wechselt.
Sie sollten wahrscheinlich versuchen, den fehlerhaften Code in Ihrem Code aufzuspüren und zu beheben.
quelle
-1
könnte nur in Entwicklungsumgebungen zu Testzwecken nützlich sein.ini_set('memory_limit', '-1');
überschreibt das Standard- PHP-Speicherlimit .quelle
-1
ist ein Wert, den PHP in diesem Zusammenhang als unbegrenzt versteht .Der richtige Weg ist, Ihre
php.ini
Datei zu bearbeiten . Bearbeiten Siememory_limit
auf Ihren Wunschwert.Da Ihre Frage
128M
(die das Standardlimit ist) überschritten wurde, stimmt etwas mit Ihrem Code nicht, da er nicht so viel kosten sollte.Wenn Sie wissen, warum es so viel kostet und Sie möchten, dass es eingestellt
memory_limit = 512M
oder höher ist, sollten Sie gut sein.quelle
Die Speicherzuordnung für PHP kann permanent oder vorübergehend 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ürmemory_limit
auf Ihren gewünschten Wert bearbeiten .Wenn Sie keinen Zugriff auf Ihre
php.ini
Datei haben (und Ihr Webhost dies zulässt), können Sie die Speicherzuordnung durch Ihre.htaccess
Datei überschreiben . Hinzufügenphp_value memory_limit 128M
(oder was auch immer Ihre gewünschte Zuordnung ist).Temporär
Sie können die Speicherzuordnung im Handumdrehen aus einer PHP-Datei heraus 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 entfernen (obwohl möglicherweise noch Computer- oder Instanzlimits gelten), indem Sie den Wert auf "-1" setzen.quelle
Es ist sehr einfach, Speicherlecks in einem PHP-Skript zu bekommen - insbesondere, wenn Sie eine Abstraktion wie ein ORM verwenden. Versuchen Sie, Ihr Skript mit Xdebug zu profilieren und herauszufinden, wo all dieser Speicher hingegangen ist.
quelle
Beim Hinzufügen von 22,5 Millionen Datensätzen zu einem Array mit array_push wurden bei etwa 20 Millionen Datensätzen immer wieder schwerwiegende Fehler "Speicher erschöpft" angezeigt, die
4G
als Speicherlimit in der Datei php.ini verwendet wurden. Um dies zu beheben, habe ich die Anweisung hinzugefügtam 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:
Der schwerwiegende Fehler zeigt auf Zeile 3, bis ich das Speicherlimit erhöht habe, wodurch der Fehler behoben wurde.
quelle
ini_set('memory_limit', '8192M');
?Ich habe diesen Fehler immer wieder erhalten, auch wenn er
memory_limit
eingestelltphp.ini
und der Wert korrekt ausgelesen wurdephpinfo()
.Indem Sie dies ändern:
Dazu:
Dies hat das Problem in PHP 7 behoben.
quelle
Wenn Sie den obigen Fehler sehen - insbesondere wenn der
(tried to allocate __ bytes)
Wert niedrig ist, könnte dies ein Indikator für eine Endlosschleife sein, wie eine Funktion, die sich selbst ohne Ausweg aufruft:quelle
Nachdem diese beiden Leitungen aktiviert wurden, funktionierte es:
quelle
Sie können dies ordnungsgemäß beheben, indem Sie
memory_limit
fastcgi / fpm ändern :Ändern Sie den Speicher von 128 auf 512, siehe unten
zu
quelle
Das Stammverzeichnis Ihrer Site:
quelle
Ändern Sie das Speicherlimit in der Datei php.ini und starten Sie Apache neu. Führen Sie nach dem Neustart die Datei phpinfo () aus. Funktion aus einer beliebigen PHP-Datei für eine
memory_limit
Änderungsbestätigung.Speicherlimit -1 bedeutet, dass kein Speicherlimit festgelegt ist. Es ist jetzt maximal.
quelle
Für Drupal-Benutzer lautet die Antwort von Chris Lane:
funktioniert, aber wir müssen es gleich nach der Eröffnung setzen
Tag in der Datei index.php im Stammverzeichnis Ihrer Site.
quelle
In Drupal 7 können Sie das Speicherlimit in der Datei settings.php ändern, die sich in Ihrem Ordner sites / default befindet. Um die Linie 260 herum sehen Sie Folgendes:
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.
quelle
Anstatt den
memory_limit
Wert in Ihrerphp.ini
Datei zu ändern, können Sie , wenn ein Teil Ihres Codes viel Speicher benötigt, denmemory_limit
Abschnitt entfernen, bevor dieser Abschnitt ausgeführt wird, und ihn anschließend ersetzen.quelle
Mit PHP 5.3+ können Sie das Speicherlimit ändern, indem Sie eine
.user.ini
Datei in denpublic_html
Ordner legen . Erstellen Sie einfach die obige Datei und geben Sie die folgende Zeile ein:Einige cPanel-Hosts akzeptieren nur diese Methode.
quelle
Absturzseite?
(Es passiert, wenn MySQL große Zeilen abfragen muss. Standardmäßig
memory_limit
ist klein eingestellt, was für die Hardware sicherer war.)Sie können den vorhandenen Speicherstatus Ihres Systems überprüfen, bevor Sie Folgendes erhöhen
php.ini
:Hier habe ich es wie im Folgenden erhöht und dann
service httpd restart
das Absturzseitenproblem behoben.quelle
free -m
Sollte man sich nach dem Ausführen des Befehls ansehen , um sich für ein neues memory_limit zu entscheiden?Fügen Sie einfach eine hinzu
ini_set('memory_limit', '-1');
Zeile oben auf Ihrer Webseite hinzu.Und Sie können Ihr Gedächtnis nach Ihren Wünschen anstelle von -1, bis
16M
usw. einstellen .quelle
Für diejenigen, die sich am Kopf kratzen, um herauszufinden, warum um alles in der Welt diese kleine Funktion einen Speicherverlust verursachen sollte, manchmal aus Versehen, ruft sich eine Funktion für immer rekursiv auf.
Beispiel: Eine Proxy-Klasse mit demselben Namen für eine Funktion des Objekts, das sie als Proxy verwenden soll.
Manchmal vergessen Sie vielleicht, dieses kleine actualObjec-Mitglied mitzubringen, und da der Proxy tatsächlich über diese
doSomething
Methode verfügt, gibt Ihnen PHP keinen Fehler. Bei einer großen Klasse kann es für einige Minuten vor den Augen verborgen sein, um herauszufinden, warum dies so ist verliert den Speicher.quelle
die('here')
Ihren Code eingeben und diese Anweisung verschieben, um zu sehen, wo die Rekursion beginnt.Ich hatte den folgenden Fehler, als ich mit einem Datensatz lief, der kleiner war als zuvor.
Als mich die Suche nach dem Fehler 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, wurden bereits 1.157 MB verwendet.
Es stellte sich heraus, dass ich über einen Zeitraum von Tagen jeweils ein 50-minütiges Video angesehen hatte, was die Dinge durcheinander brachte. Es ist die Art von Korrektur, die Experten korrigieren, ohne darüber nachzudenken, aber für Leute wie mich lohnt es sich, daran zu denken.
quelle
Führen Sie das Skript folgendermaßen aus (z. B. Cron-Fall):
php5 /pathToScript/info.php
Erzeugt denselben Fehler.Der richtige Weg:
php5 -cli /pathToScript/info.php
quelle
Wenn Sie einen WHM-basierten VPS (Virtual Private Server) ausführen, haben Sie möglicherweise keine Berechtigung zum direkten Bearbeiten von PHP.INI. Das System muss es tun. Geht in dem Host - Bedienfeld WHM, um Service - Konfiguration → PHP Configuration Editor und ändern
memory_limit
:quelle
Ich finde es nützlich , wenn mit oder erfordern
_dbconnection.php_
und_functions.php
in Dateien , die tatsächlich verarbeitet werden, anstatt im Header enthält. Welches ist in sich enthalten.Wenn Ihre Kopf- und Fußzeile enthalten ist, fügen Sie einfach alle Ihre Funktionsdateien hinzu, bevor die Kopfzeile enthalten ist.
quelle
Die Verwendung
yield
könnte ebenfalls eine Lösung sein. Siehe Generatorsyntax .Anstatt die
PHP.ini
Datei für einen größeren Speicher zu ändern , kannyield
das Problem manchmal durch Implementieren einer Schleife behoben werden. Der Ertrag besteht darin, nicht alle Daten auf einmal zu sichern, sondern sie einzeln zu lesen, wodurch viel Speicherplatz gespart wird.quelle
PHP.ini
? Ist es nichtphp.ini
?Dieser Fehler wird manchmal durch einen Fehler im PHP-Code verursacht, der Rekursionen mit Ausnahmebehandlung und möglicherweise anderen Vorgängen verursacht. Leider konnte ich kein winziges Beispiel erstellen.
In diesen Fällen, die bei mir mehrmals aufgetreten sind,
set_time_limit
schlägt dies fehl und der Browser versucht weiterhin, die PHP-Ausgabe zu laden, entweder mit einer Endlosschleife oder mit der schwerwiegenden Fehlermeldung, die das Thema dieser Frage ist.Durch Reduzieren der zulässigen Zuordnungsgröße durch Hinzufügen
Am Anfang Ihres Codes sollten Sie in der Lage sein, den schwerwiegenden Fehler zu verhindern.
Dann bleibt möglicherweise ein Programm übrig, das beendet wird, aber immer noch schwer zu debuggen ist.
Fügen Sie zu diesem Zeitpunkt
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:
Das Argument $ LoopSite kann der Name einer Funktion in Ihrem Code sein. Dies ist nicht unbedingt erforderlich, da die Fehlermeldung Sie auf die Zeile verweist, die den Aufruf von BreakLoop () enthält.
quelle
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.
quelle
Als ich die folgenden Zeilen aus meinem Code entfernt habe, hat alles funktioniert!
Diese Zeilen waren in jeder Datei enthalten, die ich ausgeführt habe. Beim Ausführen der Dateien nacheinander funktionierten alle einwandfrei, aber beim Ausführen aller Dateien zusammen trat das Problem mit dem Speicherverlust auf. Irgendwie schließt das "include_once" die Dinge nicht einmal ein, oder ich mache etwas falsch ...
quelle
set_include_path(get_include_path() . get_include_path().'/phpseclib');
Dadurch wird der Pfad '/ phpseclib' einmal für jede Datei mit der Zeile hinzugefügt ... damit er mehrmals hinzugefügt werden kann! Ich würde vorschlagen, es in eine Einstellungsdatei undinclude_once
die Einstellungsdatei zu legen .