2010-11-06 3 views
3

J'ai écrit un démon en php et je veux m'assurer qu'il ne fuit pas la mémoire, car il fonctionnera 24/7.démon php fuite de mémoire possible

même dans sa forme la plus simple, memory_get_peak_usage pour un démon rapportera que le script consomme plus de mémoire pour chaque cycle. memory_get_usage d'autre part ne va pas grandir. La question est: est-ce que je devrais m'inquiéter? J'ai démonté le démon pour les bases nues, mais cela se passe toujours. Des pensées?

#!/usr/bin/php -q 

<?php 
require_once "System/Daemon.php"; 
System_Daemon::setOption("appName", "smsd"); 
System_Daemon::start(); 
while(!System_Daemon::isDying()){ 
System_Daemon::info("debug: memory_get_peak_usage: ".memory_get_peak_usage()); 
System_Daemon::info("debug: memory_get_usage: ".memory_get_usage()); 
System_Daemon::iterate(2); 
} 

NOTE FINALE + CONCLUSION: i fini par écrire mon propre enveloppe de démon, ne pas utiliser la system_daemon de poire. indépendamment de la façon dont j'ai tweaked cette bibliothèque je ne pouvais pas l'empêcher de fuir la mémoire. J'espère que ceci aide quelqu'un d'autre.

NOTE FINALE + CONCLUSION 2: mon script est en production depuis plus d'une semaine et ne perd pas 1 octet de mémoire. Donc - écrire un démon en php semble être correct, tant que vous êtes très prudent sur sa consommation de mémoire.

+0

Le partage de votre wrapper démon serait génial;) – Xeoncross

+1

@Xeoncross désolé pour la réponse tardive. mais ouais bien. Il s'agit simplement d'une boucle infinie qui utilise un certain temps avant d'itérer. rien de plus. Assurez-vous simplement d'enregistrer memory_get_peak_usage() pour chaque itération. De cette façon, vous verrez si vous avez des fuites de mémoire. – fjallstrom

Répondre

5

J'ai eu le même problème. Peut-être la meilleure idée est de signaler nouveau bug à PEAR

BTW, le code comme ça ne montre pas que fuite de mémoire:

#!/usr/bin/php -q 

<?php 
require_once "System/Daemon.php"; 
System_Daemon::setOption("appName", "smsd"); 
System_Daemon::start(); 
while(!System_Daemon::isDying()) { 
print ("debug: memory_get_peak_usage: ".memory_get_peak_usage()."\n"); 
print ("debug: memory_get_usage: ".memory_get_usage()."\n\n"); 
System_Daemon::iterate(2); 

} 

Regardez comme de System_Daemon :: info() est un problème.

+1

vraiment excellente réponse! – fjallstrom

2

Vous pouvez essayer d'utiliser le nouveau garbage collector dans PHP 5.3 pour éviter les problèmes avec les références circulaires.

+0

merci, va essayer gc_collect_cycles, c'était une nouvelle pour moi! – fjallstrom

+0

Pour info, nous avons écrit un script 'daemon' qui est utilisé sur tweetsms.com. C'est un script PHP 5.3 qui utilise Doctrine (mappeur DB ORM), lance d'autres commandes et enregistre les messages de journalisation dans la base de données (via doctrine). J'ai vérifié aujourd'hui, et le démon fonctionnait depuis plus de 4 mois sans augmenter l'utilisation de la mémoire. Nous appelons gc_collect_cycles() après chaque boucle juste au cas où. – CAMason

0

Vous ne devriez pas use PHP to write a daemon. Pourquoi? Parce que PHP n'est pas un langage suffisamment mature pour fonctionner pendant des heures, des jours, des semaines ou des mois. PHP est écrit en C, toute la magie qu'il fournit doit être gérée. La récupération de place, en fonction de votre version, peut ou non fonctionner, selon les extensions que vous avez compilées et utilisées. Oui, s'ils sont livrés avec des versions officielles, ils devraient "bien jouer", mais vérifiez-vous pour voir quelle version vous utilisez? Êtes-vous sûr que toutes les extensions chargées se rendent compte qu'elles peuvent fonctionner pendant plus de 10 à 30 secondes? Étant donné que la plupart des temps d'exécution ne fuient jamais, êtes-vous sûr que cela fonctionne même?

Je suis assez près d'aller sur un 'don't use regex to parse HTML rant' à ce sujet, car je vois la question rampant de plus en plus. Deux fois aujourd'hui que je suis au courant. Utiliseriez-vous un pied-de-biche comme cure-dent? Ni Zend, ni Roadsend, ni PHC ne sont suffisamment matures pour pouvoir fonctionner pendant une période de temps qui pourrait être considérée comme prolongée, compte tenu de la durée de vie attendue d'un processus PHP lors du rendu d'une page Web. Oui, même avec les fonctionnalités GC fournies par le compilateur PHP basé sur C++, il est imprudent d'écrire un démon en PHP.

Je déteste les réponses qui disent you can't do that, with that, mais dans ce cas, c'est vrai, au moins pour l'instant.

+0

vous avez probablement raison, je viens d'être beaucoup mieux avec php que de dire, c. il va effectuer une tâche assez simple, donc je vais probablement essayer de toute façon. va le laisser fonctionner pendant une semaine ou deux, sur une boîte de dev. – fjallstrom

+3

Je ne suis pas sûr que cela soit vrai avec PHP 5.3. Depuis que nous avons récupéré la corbeille, j'ai eu beaucoup de succès avec des démons PHP (jours) longs même sous une charge importante. Même s'il est vrai que PHP a un très mauvais support de démon, j'essaye de changer cela avec [LooPHP] (https://github.com/Wordi/LooPHP). –

+2

@Kendall Hopkins - Presque toutes les réponses sur SO ont été répondues près du moment où la question a été posée, à quelques exceptions près. À ce jour, mon conseil demeure, n'utilisez pas PHP pour les processus système. Si vous le faites, assurez-vous qu'une version agréable de PHP est en cours d'exécution, si PHP doit démontrer un GC stable et fonctionnel. Vous pourriez envisager d'ajouter une réponse. –

4

Il s'est avéré que file_get_contents fuyait de la mémoire. Chaque fois que je désactivais cette ligne, l'utilisation maximale de la mémoire était stable. Lorsque je l'ai commenté, l'utilisation maximale de la mémoire augmentait de 32 octets à chaque itération.

Replaced l'appel file_get_contents (utilisé pour récupérer le numéro dans le fichier pid dans/var/run) avec fread, et résolu ce problème. Ce correctif fera partie de la prochaine version de System_Daemon.

Merci à quiconque (ne peut pas trouver nick correspondant) a également signalé ce bug (#18036) sinon je ne l'aurais probablement jamais connu.

Merci encore!