2010-03-05 3 views
1

Tous,Zend php memory memory_limit

Je travaille sur une application Web basée sur Zend Framework. Nous continuons à rencontrions des erreurs de mémoire sur notre serveur dev:

taille de la mémoire autorisée de XXXX octets épuisé (... AAAA essayé

Nous continuons à memory_limit de plus en plus php.ini, mais il est maintenant plus de 1000 mégas . Ce qui est une valeur memory_limit normale? Quels sont les suspects habituels en php/Zend pour l'exécution de mémoire? Nous utilisons le Propel ORM.

Merci pour toute l'aide!

Mise à jour I ne peut pas reproduire cette erreur dans mon environnement Windows . Si je mets memory_limit bas (disons 16M), j'obtiens la même erreur, mais le montant "essayé d'allouer" est toujours quelque chose de raisonnable. Par exemple: (essayé d'allouer 13344 octets) Si je mets la mémoire très bas sur le serveur (Fedora 9) (comme 16M), je reçois la même chose. erreurs de mémoire cohérentes et raisonnables. Cependant, même lorsque la limite de mémoire est fixée très haut sur notre serveur (128M, par exemple), peut-être une fois par semaine, j'obtiendrai une énorme erreur de mémoire folle: (essaye d'allouer 1846026201 octets). Je ne sais pas si cela pourrait éclairer davantage ce qui se passe. Nous utilisons propel 1.5. Il semble que la version actuelle sortira plus tard ce mois-ci, mais il ne semble pas que quelqu'un d'autre ait ce problème de toute façon. Je ne sais pas que Propel est le problème. Nous utilisons Zend Server avec PHP 5.2 sur la machine Linux et 5.3 localement.

D'autres idées? J'ai un ticket pour installer Xdebug sur la machine Linux.

Merci,

-rep

+0

Les requêtes doivent être de l'ordre de 10-20 Mo pour les éléments de base. On dirait que vous essayez de récupérer un grand ensemble de données en utilisant Propel (comme une table SELECT * FROM avec beaucoup de lignes) comme d'autres l'ont dit –

+0

Les montants que PHP a essayé d'allouer sont totalement hors de propos. Ils montrent juste le montant qui est arrivé à être demandé au moment où le script a atteint la limite de la mémoire. –

+0

Voir si ma réponse aide: http://stackoverflow.com/a/11157739/881736 – Andy

Répondre

0

Je pense que cela a quelque chose à voir avec le déploiement de régulateur de vitesse. Je reçois seulement l'erreur de mémoire très élevée (sur l'ordre des concerts) quand quelqu'un déploie le nouveau code (ou juste après que le nouveau code ait été déployé). Cela a aussi un peu de sens puisque l'erreur pointe toujours vers une ligne "require_once". Chaque fois que je reçois une erreur: Erreur fatale: mémoire (alloué 4.456.448) (a essayé d'allouer 3949907977 octets) dans /directory/file.php sur la ligne 2

J'ai remplacé la ligne « require_once » avec: class_exists ('Ingrain_Security_Auth') || require ('Ingrain/Security/Auth.php');

J'ai remplacé cette ligne dans 3 fichiers jusqu'à présent, et n'ai plus eu de problèmes de mémoire. Quelqu'un peut-il faire la lumière sur ce qui pourrait se passer? J'utilise Cruise Control pour déployer.

0

Quelle est exactement votre application faire au moment où il est à court de mémoire. Il peut y avoir beaucoup de causes pour cela. Je dirais que le plus commun serait d'allouer trop de données à un tableau. Votre application fait-elle quelque chose dans ce sens?

+0

Le problème est, cette erreur est intermittente, et jamais au même endroit. Parfois, cela se produit même lors de la déconnexion. Sur une période de deux ou trois semaines, il est probablement arrivé moins de 10 fois, il est donc difficile de dire ce qui se passe quand la mémoire est épuisée. Selon vous, quelle serait la meilleure approche pour restreindre le code incriminé? – RepDetec

+0

Les deux dernières fois j'ai eu l'erreur, il a été pour la ligne suivante: require_once 'Security/Auth.php'; Pensez-vous qu'il y a quelque chose à cela, ou que c'est juste parce que c'est l'une des premières lignes touchées? – RepDetec

+0

Si vos journaux d'erreurs ne révèlent rien, vous pouvez profiler votre code PHP.Il peut vous aider à déterminer combien de temps les fonctions fonctionnent et plus http://stackoverflow.com/questions/133686/what-is-the-best-way-to-profile-php-code – KTastrophy

0

Vous avez une des deux choses qui se passent, peut-être à la fois:

  1. Vous avez un processus d'emballement quelque part qui n'est pas à sa fin quand il devrait être.
  2. Vous avez des algorithmes qui envoient beaucoup de données, comme des chaînes ou des tableaux ou des objets énormes, et qui font des copies inutiles au lieu de traiter ce dont ils ont besoin et de rejeter ce qu'ils ne font pas.
+0

Il semble que la ligne qui est épuisante de la mémoire est toujours un require_once pour l'un des deux fichiers. Qu'est-ce qui se passe réellement pendant un "require_once?" Ne pas simplement analyser le fichier? – RepDetec

+0

Il exécute le fichier. La plupart du temps, ces fichiers sont simplement des déclarations de fonctions et de classes, mais ils peuvent aussi contenir du code immédiat. J'ai vu des frameworks faire des choses stupides avec des objets énormes juste pour s'initialiser. Je n'aurais pas pensé que Zend aurait ce problème - il pourrait charger une énorme quantité de données de quelque part. – staticsan

4

D'une manière générale, avec PHP 5.2 et/ou PHP 5.3, j'ai tendance à considérer que plus de 32M pour memory_limit est "trop":

  • utilisation des cadres/ORM et des trucs comme ça, 16M est souvent pas assez
  • 32M est assez en utilisant généralement le genre d'applications web sur lesquels je travaille (sites typiques)
  • Utilisation de plus de 64M signifie que le serveur ne pourra pas gérer autant d'utilisateurs que nous le souhaiterions.


Quand il vient à un script pour atteindre memory_limit, le problème habituel tente de charger des données trop en mémoire; quelques exemples:

  • Chargement d'un gros fichier en mémoire, avec des fonctions telles que file ou file_get_contents, ou des fonctions liées à XML/classes
  • Création d'un tableau trop grand de données
  • Création d'un trop grand nombre d'objets

Considérant que vous utilisez un ORM, vous pourriez être dans une situation où:

  • Vous faites une requête SQL qui renvoie un grand nombre de lignes
  • Votre ORM convertit chaque ligne des objets, mettre ceux dans un tableau
  • Dans ce cas, une solution serait de charger moins de données
    • utilisant pagination, par exemple
    • ou en essayant de charger des données sous forme de tableaux à la place des objets (Je ne sais pas si cela est possible avec Propel - mais c'est avec Doctrine; alors peut-être que Propel a un moyen de le faire aussi?)