J'ai un tas de systèmes de point de vente (POS) client qui envoient régulièrement de nouvelles données de vente à une base de données centralisée, qui stocke les données dans une grande base de données pour la génération de rapports.
Le POS client est basé sur PHPPOS, et j'ai implémenté un module qui utilise la bibliothèque XML-RPC standard pour envoyer des données de vente au service. Le système serveur est construit sur CodeIgniter et utilise les bibliothèques XML-RPC et XML-RPCS pour le composant de service Web. Chaque fois que j'envoie beaucoup de données sur les ventes (aussi peu que 50 lignes de la table des ventes et des lignes individuelles de sales_items relatives à chaque article de la vente), j'obtiens l'erreur suivante:
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 54 bytes)
128M est la valeur par défaut php.ini
, mais je suppose que c'est un nombre énorme à casser. En fait, j'ai même essayé de définir cette valeur à 1024M, et tout ce qu'il faut, c'est prendre plus de temps pour l'erreur.
En ce qui concerne les mesures que j'ai prises, j'ai essayé de désactiver tous les traitements côté serveur et je les ai truqués pour renvoyer une réponse standardisée quelle que soit l'entrée. Cependant, je pense que le problème réside dans l'envoi réel des données. J'ai même essayé de désactiver le temps d'exécution maximal du script pour PHP, et cela continue de produire des erreurs.
la source
ini_set('memory_limit', '256M');
Réponses:
Changer le
memory_limit
byini_set('memory_limit', '-1');
n'est pas une bonne solution. S'il vous plaît ne faites pas ça.Votre code PHP peut avoir une fuite de mémoire quelque part et vous dites au serveur d'utiliser simplement toute la mémoire qu'il souhaite. Vous n'auriez pas résolu le problème du tout. Si vous surveillez votre serveur, vous verrez qu'il utilise maintenant probablement la plus grande partie de la RAM et qu'il est même échangé sur le disque.
Vous devriez probablement essayer de retrouver le code incriminé dans votre code et de le corriger.
la source
-1
ne pourrait être utile que dans des environnements de développement à des fins de test.ini_set('memory_limit', '-1');
remplace la limite de mémoire PHP par défaut .la source
-1
est une valeur que PHP considère comme illimitée dans ce contexte.La bonne façon est de modifier votre
php.ini
fichier. Modifiezmemory_limit
à votre valeur désirée.À partir de votre question,
128M
(qui est la limite par défaut) a été dépassée, il y a donc quelque chose de grave avec votre code car il ne devrait pas en prendre autant.Si vous savez pourquoi cela prend autant et que vous souhaitez lui permettre de définir
memory_limit = 512M
ou supérieur et vous devriez être bon.la source
L'allocation de mémoire pour PHP peut être ajustée de manière permanente ou temporaire.
En permanence
Vous pouvez modifier définitivement l'allocation de mémoire PHP de deux manières.
Si vous avez accès à votre
php.ini
fichier, vous pouvez modifier la valeurmemory_limit
de votre valeur désirée.Si vous n'avez pas accès à votre
php.ini
fichier (et que votre hébergeur le permet), vous pouvez remplacer l'allocation de mémoire via votre.htaccess
fichier. Ajoutezphp_value memory_limit 128M
(ou quelle que soit votre allocation souhaitée).Temporaire
Vous pouvez ajuster l'allocation de mémoire à la volée à partir d'un fichier PHP. Vous avez simplement le code
ini_set('memory_limit', '128M');
(ou quelle que soit votre allocation souhaitée). Vous pouvez supprimer la limite de mémoire (bien que des limites de machine ou d'instance puissent toujours s'appliquer) en définissant la valeur sur "-1".la source
Il est très facile d'obtenir des fuites de mémoire dans un script PHP - surtout si vous utilisez l'abstraction, comme un ORM. Essayez d'utiliser Xdebug pour profiler votre script et découvrir où est passée toute cette mémoire.
la source
Lors de l'ajout de 22,5 millions d'enregistrements dans un tableau avec array_push, je continuais à obtenir des erreurs fatales "mémoire épuisée" à environ 20 millions d'enregistrements en utilisant
4G
comme limite de mémoire dans le fichier php.ini. Pour résoudre ce problème, j'ai ajouté la déclarationen haut du fichier. Maintenant, tout fonctionne bien. Je ne sais pas si PHP a une fuite de mémoire. Ce n'est pas mon travail et je m'en fiche. Je dois juste faire mon travail, et cela a fonctionné.
Le programme est très simple:
L'erreur fatale pointe vers la ligne 3 jusqu'à ce que j'augmente la limite de mémoire, ce qui élimine l'erreur.
la source
ini_set('memory_limit', '8192M');
?J'ai continué à obtenir cette erreur, même avec
memory_limit
set inphp.ini
, et la valeur se lisait correctement avecphpinfo()
.En le changeant de ceci:
Pour ça:
Cela a corrigé le problème dans PHP 7.
la source
Lorsque vous voyez l'erreur ci-dessus - surtout si la
(tried to allocate __ bytes)
valeur est faible, cela pourrait être un indicateur d'une boucle infinie, comme une fonction qui s'appelle sans issue:la source
Après avoir activé ces deux lignes, il a commencé à fonctionner:
la source
Vous pouvez corriger cela correctement en changeant
memory_limit
sur fastcgi / fpm:Changez la mémoire, comme de 128 à 512, voir ci-dessous
à
la source
Répertoire racine de votre site:
la source
Modifiez la limite de mémoire dans le fichier php.ini et redémarrez Apache. Après le redémarrage, exécutez phpinfo (); fonctionner à partir de n'importe quel fichier PHP pour une
memory_limit
confirmation de modification.La limite de mémoire -1 signifie qu'aucune limite de mémoire n'est définie. C'est maintenant au maximum.
la source
Pour les utilisateurs de Drupal, cette réponse de Chris Lane:
fonctionne mais nous devons le mettre juste après l'ouverture
dans le fichier index.php du répertoire racine de votre site.
la source
Dans Drupal 7, vous pouvez modifier la limite de mémoire dans le fichier settings.php situé dans votre dossier sites / default. Autour de la ligne 260, vous verrez ceci:
Même si vos paramètres php.ini sont suffisamment élevés, vous ne pourrez pas consommer plus de 128 Mo si cela n'est pas défini dans votre fichier Drupal settings.php.
la source
Plutôt que de modifier la
memory_limit
valeur de votrephp.ini
fichier, s'il y a une partie de votre code qui pourrait utiliser beaucoup de mémoire, vous pouvez supprimermemory_limit
avant l'exécution de cette section, puis la remplacer après.la source
PHP 5.3+ vous permet de modifier la limite de mémoire en plaçant un
.user.ini
fichier dans lepublic_html
dossier. Créez simplement le fichier ci-dessus et saisissez-y la ligne suivante:Certains hôtes cPanel n'acceptent que cette méthode.
la source
Crash page?
(Cela se produit lorsque MySQL doit interroger de grandes lignes. Par défaut, il
memory_limit
est défini sur petit, ce qui était plus sûr pour le matériel.)Vous pouvez vérifier l'état de la mémoire existante de votre système, avant d'augmenter
php.ini
:Ici, je l'ai augmenté comme ci-dessous, puis je
service httpd restart
résous le problème de la page de blocage.la source
free -m
commande pour décider d'un nouveau memory_limit?Ajoutez simplement une
ini_set('memory_limit', '-1');
ligne en haut de votre page Web.Et vous pouvez définir votre mémoire selon vos besoins à la place de -1, à
16M
, etc.la source
Pour ceux qui se grattent la tête pour savoir pourquoi diable cette petite fonction devrait provoquer une fuite de mémoire, parfois par une petite erreur, une fonction commence à s'appeler récursivement pour toujours.
Par exemple, une classe proxy qui porte le même nom pour une fonction de l'objet qui va la proxy.
Parfois, vous pouvez oublier d'apporter ce petit membre actualObjec et parce que le proxy a réellement cette
doSomething
méthode, PHP ne vous donnera aucune erreur et pour une grande classe, il pourrait être caché aux yeux pendant quelques minutes pour savoir pourquoi il fuit la mémoire.la source
die('here')
votre code et déplacer cette instruction pour voir où commence la récursivité.J'ai eu l'erreur ci-dessous lors de l'exécution sur un ensemble de données plus petit que ce qui avait fonctionné précédemment.
Comme la recherche de la faute m'a amené ici, j'ai pensé mentionner que ce n'est pas toujours les solutions techniques dans les réponses précédentes, mais quelque chose de plus simple. Dans mon cas, c'était Firefox. Avant d'exécuter le programme, il utilisait déjà 1 157 Mo.
Il s'est avéré que j'avais regardé une vidéo de 50 minutes un peu à la fois sur une période de plusieurs jours et cela a tout gâché. C'est le genre de correctif que les experts corrigent sans même y penser, mais pour moi, cela vaut la peine de garder à l'esprit.
la source
Exécuter le script comme ceci (cas cron par exemple):
php5 /pathToScript/info.php
produit la même erreur.La bonne façon:
php5 -cli /pathToScript/info.php
la source
Si vous exécutez un VPS (serveur privé virtuel) propulsé par WHM, vous constaterez peut-être que vous n'avez pas l'autorisation de modifier directement PHP.INI; le système doit le faire. Dans le panneau de configuration de l'hôte WHM, accédez à Configuration du service → Éditeur de configuration PHP et modifiez
memory_limit
:la source
Je trouve cela utile lors de l'inclusion ou de la demande
_dbconnection.php_
et_functions.php
dans des fichiers réellement traités, plutôt que de l'inclure dans l'en-tête. Ce qui est inclus en soi.Donc, si votre en- tête et pied de page est inclus, incluez simplement tous vos fichiers fonctionnels avant que l'en-tête ne soit inclus.
la source
L'utilisation
yield
pourrait également être une solution. Voir Syntaxe du générateur .Au lieu de modifier le
PHP.ini
fichier pour un stockage de mémoire plus important, l'implémentation d'yield
une boucle interne peut parfois résoudre le problème. Ce que fait le rendement, au lieu de vider toutes les données à la fois, il les lit une par une, ce qui économise beaucoup d’utilisation de la mémoire.la source
PHP.ini
? N'est-ce pasphp.ini
?Cette erreur est parfois causée par un bogue dans le code PHP qui provoque des récursions impliquant la gestion des exceptions et éventuellement d'autres opérations. Malheureusement, je n'ai pas pu créer un petit exemple.
Dans ces cas, ce qui m'est arrivé plusieurs fois,
set_time_limit
échoue, et le navigateur continue d'essayer de charger la sortie PHP, soit avec une boucle infinie, soit avec le message d'erreur fatal qui est le sujet de cette question.En réduisant la taille d'allocation autorisée en ajoutant
vers le début de votre code, vous devriez pouvoir empêcher l'erreur fatale.
Ensuite, vous pouvez vous retrouver avec un programme qui se termine, mais est toujours difficile à déboguer.
À ce stade, insérez des
BreakLoop()
appels dans votre programme pour prendre le contrôle et découvrir quelle boucle ou récursivité dans votre programme est à l'origine du problème.La définition de BreakLoop est la suivante:
L'argument $ LoopSite peut être le nom d'une fonction dans votre code. Ce n'est pas vraiment nécessaire, car le message d'erreur que vous obtiendrez vous dirigera vers la ligne contenant l'appel BreakLoop ().
la source
Dans mon cas, c'était un bref problème avec la façon dont une fonction était écrite. Une fuite de mémoire peut être provoquée en affectant une nouvelle valeur à la variable d'entrée d'une fonction, par exemple:
la source
Lorsque j'ai supprimé les lignes suivantes de mon code, tout a bien fonctionné!
Ces lignes étaient incluses dans chaque fichier que j'exécutais. Lors de l'exécution des fichiers un par un, tout fonctionnait bien, mais lors de l'exécution de tous les fichiers ensemble, j'ai eu le problème de fuite de mémoire. D'une certaine manière, le "include_once" n'inclut pas les choses une fois, ou je fais quelque chose de mal ...
la source
set_include_path(get_include_path() . get_include_path().'/phpseclib');
Cela ajoutera le chemin '/ phpseclib' une fois pour chaque fichier qui a la ligne ... afin qu'il puisse l'ajouter plusieurs fois! Je suggère de le mettre dans un fichier de paramètres etinclude_once
le fichier de paramètres.