web-dev-qa-db-fra.com

PHP erreur de mémoire insuffisante même si memory_limit n'est pas atteint

Je viens d'hériter d'un site avec un script PHP qui manque constamment de mémoire à 117 Mo. Cela se produit même lorsque j'augmente la variable memory_limit de PHP à 312 Mo, ce que je fais via php .ini.

Ceci est maintenant résolu grâce à un excellent indice de pcguru. Voir ma réponse ci-dessous qui commence: J'ai enfin trouvé la réponse

ini_get('memory_limit') renvoie la valeur définie dans php.ini, donc je suis certain qu'Apache a redémarré après avoir changé la valeur. J'utilise memory_get_usage(true) pour renvoyer la mémoire consommée par le script à différents moments du parcours. Et il échoue constamment lorsqu'il atteint 117 Mo.

Y a-t-il une limite interne PHP je ne suis pas au courant qui n'a jamais alloué plus de 117 Mo à un script individuel?

Le serveur a 1 Go de RAM et exécute CentOS. J'ai un accès root à Shell. PHP est la version 5.3.18. MySQL est la version 5.1.66-cll .

Ce script est derrière un nom d'utilisateur/mot de passe et je ne peux pas lui fournir d'accès public.

Modifié pour ajouter:

1) Merci à tous pour votre aide à ce jour. Vous trouverez plus d'informations dans mes réponses aux commentaires d'utilisateurs spécifiques sous différentes réponses ci-dessous.

2) Suhosin n'est certainement pas installé. J'ai vérifié à plusieurs endroits, y compris l'exécution d'un script et la vérification des constantes et l'exécution de php -v

3) Le journal Apache n'a aucun enregistrement du message d'erreur spécifique que je reçois. La journalisation est activée dans php.ini. J'ai parcouru grep pour rechercher le journal entier.

4) Est-il possible que la mauvaise erreur soit signalée dans ce cas?

20
user8109

J'ai enfin trouvé la réponse. L'indice est venu de la réponse de pcguru commençant par "puisque le serveur n'a que 1 Go de RAM ...".

Sur une intuition, j'ai cherché à voir si Apache avait ses propres limites de mémoire car celles-ci étaient susceptibles d'affecter la capacité de PHP à allouer de la mémoire. En haut de httpd.conf, j'ai trouvé cette déclaration: RLimitMEM 204535125

Ceci est mis là par whm/cpanel. Selon la page Web suivante, whm/cpanel calcule incorrectement sa valeur sur un serveur virtuel ... http://forums.jaguarpc.com/vps-dedicated/17341-Apache-memory-limit-rlimitmem.html =

Le script qui manque de mémoire obtient la majeure partie du chemin, j'ai donc augmenté RLimitMEM à 268435456 (256 Mo) et relancé le script. Il a terminé sa fusion de baies et produit le fichier csv à télécharger.

ETA: Après avoir lu davantage sur RLimitMEM et RLimitCPU, j'ai décidé de les supprimer de httpd.conf. Cela permet à ini_set ('memory_limit', '### M') de fonctionner, et je donne maintenant à ce script particulier la mémoire supplémentaire dont il a besoin. J'ai également doublé le RAM sur ce serveur.

Merci à tous pour votre aide dans la détection de ce problème plutôt épineux, et en particulier à pcguru qui a trouvé l'indice essentiel qui m'a permis de trouver la solution.

20
user8109

Étant donné que le serveur ne dispose que de 1 Go de RAM je penche vers la possibilité que vous ayez réellement complètement épuisé la mémoire système.

Voir ce fil . Vous obtenez le même "PHP Fatal error: Out of memory" au lieu du plus commun "Fatal error: Allowed memory size of ...". Votre erreur indique que le système ne peut pas allouer plus de mémoire, ce qui signifie que même les fonctions internes de PHP ne peuvent pas allouer plus de mémoire, sans parler de votre propre code.

Comment est configuré PHP pour fonctionner avec Apache? En tant que module ou CGI? Combien de processus PHP pouvez-vous exécuter en même temps? Avez-vous espace d'échange disponible?

Si vous utilisez PHP comme module dans Apache, Apache a la mauvaise habitude de conserver la mémoire allouée par le processus PHP. Devinez car il ne peut pas redémarrer le PHP module dans l'ouvrier, redémarrez entièrement l'ouvrier. Chaque ouvrier qui a servi PHP devient simplement le PHP limite de mémoire au fil du temps car ce travailleur sert un script qui alloue beaucoup de RAM. Donc, si vous avez plusieurs travailleurs en même temps, chacun utilisant 100 Mo et plus, vous manquerez rapidement de RAM. Essayez de limiter le nombre de travailleurs simultanés dans Apache .

8
oldwizard

Ce n'est peut-être pas la réponse à votre problème, mais si vous exécutez PHP à partir de la ligne de commande, vous pouvez remplacer la limite de mémoire de php.ini.

php -d memory_limit=321M my_script.php

Je ne sais pas exactement quelle est la limite de mémoire par défaut via cli.

Vous pouvez également exécuter php --ini et vérifiez les résultats.

2
aebersold

Ce n'est pas une réponse à la raison pour laquelle votre script se meurt après une certaine utilisation de la mémoire, mais vous pouvez le contourner en supprimant la limite de mémoire entièrement dans le script PHP lui-même:

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

C'est dangereux. Si vous avez un script incontrôlable, PHP prendra de la mémoire jusqu'à ce que votre serveur n'en ait plus à allouer et tombe. Vous ne devez donc l'utiliser que si vous êtes sûr le script lui-même n'est pas un problème, et uniquement pour tester la sortie.

Quant à savoir si PHP a une limite par script sur l'utilisation de la mémoire, non. J'ai personnellement exécuté des scripts avec près de 1 Go de mémoire.

2
K.A.F.