Script PHP : Problème de mémoire

Consultez la formation à Google Analytics de WebRankInfo / Ranking Metrics

theJB
WRInaute occasionnel
WRInaute occasionnel
 
Messages: 411
Inscription: 7 Avr 2006

Script PHP : Problème de mémoire

Message le Jeu Juil 31, 2008 13:44

Je remarque un truc étrange sur mon serveur..

J'ai un script php qui parse un flux xml (>1Go) avec xml reader. Le script prend 5min a s'executer et grignote petit à petit la RAM disponible. Le serveur a 2Gb de RAM, et à la fin du script, 1.8Gb sont pris.

Et mon problème, que je trouve assez bizard, c'est que une fois l'execution terminée les 1.8Gb du scripts restent occupés.. même une heure après.. et je comprends pas.

Faut-il faire qqch comme un mysql_free_result mais pour php?

Et encore un truc bizard, j'utilise top en SSH pour connaitre la mémoire occupée par mon script, et d'après cette commande, mon scripts n'utilise jamais plus de 3% de la mémoire..

Bref je comprends pas..


Bool
WRInaute passionné
WRInaute passionné
 
Messages: 1290
Inscription: 26 Fév 2004

Message le Jeu Juil 31, 2008 13:58

Hello,

le script en question tu le lances via Apache ? Si c'est le cas, il y a des chances pour qu'il faille relancer Apache après pour libérer la mémoire (oui c'est chiant, c'est pour ça que ce genre de traitement est généralement fait via CLI).

Simple vérification : tu ne charges tout de même pas tout le contenu du fichier en mémoire, si ?

Sinon coté fuite mémoire, utilises-tu preg_match() dans ta boucle ?
En effet sous Debian PHP est compilé avec une vieille version de la librairie PCRE qui a de vilaines fuites mémoire selon les expressions utilisées.

theJB
WRInaute occasionnel
WRInaute occasionnel
 
Messages: 411
Inscription: 7 Avr 2006

Message le Jeu Juil 31, 2008 14:17

Oui, j'utilise apache pour le script php.

Mais, je ne mets pas le tout flux en mémoire (heureusement :) ). Simplexml met le flux en mémoire, moi j'utilise xmlreader justement car il fonctionne en mode pull avec un pointeur qui dépile au fur et à mesure le feed, sans avoir à en stocker l'intérgralité en memoire.

D'après toi, l'execution en CLI de mon script me ferait libérer la mémoire automatiquement sans rien faire?


Autre remarque, quand je relance le script une deuxième fois, il ne reste plus que 0,2 Go de libre en RAM, mais paradoxalement tout ce passe bien, alors que la fois d'avant il m'avait pris 1,8Go..

(PS. pas de preg_match utilisé)


Bool
WRInaute passionné
WRInaute passionné
 
Messages: 1290
Inscription: 26 Fév 2004

Message le Jeu Juil 31, 2008 14:24

Oui, si PHP est lancé en CLI la mémoire qu'il consomme est libérée à la fin du traitement (mais ce n'est pas une raison pour consommer autant non plus). De plus via CLI tu devrais voir plus facilement la consommation mémoire "réelle" du processus.

Je connais le fonctionnement de XMLReader, mais on ne sait jamais, on voit un peu de tout ici ;) En tous cas que ce soit un bug interne à PHP ou un bug lié à ton script, tu as sérieuse fuite quelque part.

Essayes de débugger ça à coup de memory_get_usage().

theJB
WRInaute occasionnel
WRInaute occasionnel
 
Messages: 411
Inscription: 7 Avr 2006

Message le Jeu Juil 31, 2008 14:36

Voila ce que me donne le memory_get_usage() : 44496 ...
Et ce en plein execution du script..

Je teste de suite la commande en CLI

theJB
WRInaute occasionnel
WRInaute occasionnel
 
Messages: 411
Inscription: 7 Avr 2006

Message le Jeu Juil 31, 2008 14:39

Bon j'ai testé en CLI, à la fin du script, pas de libération de la mémoire, et idem en restartant apache, je dois à chq fois rebooter le serveur.

J'ai essayé avec une version du script simplifé, j'ai toujours le même problème.

Et voila le code du script simplifié :

Code: Tout sélectionner
$reader = new XMLReader();
$reader->open('ftp_feeds/feed_big.xml');

while ($reader->read())
{

}
$reader->close();

unset($reader);


Tu as une idée? c'est xmlreader qui a un pb?


Bool
WRInaute passionné
WRInaute passionné
 
Messages: 1290
Inscription: 26 Fév 2004

Message le Jeu Juil 31, 2008 14:56

T'es sûr de ton coup là ? Je fais ce genre de choses depuis longtemps avec des fichiers XML assez gros (400Mo le plus gros), et ça ne pose aucun soucis le script ne consomme rien (ou presque).

Ton script ne contient que ça ? Et... comment mesures-tu la consommation mémoire avant, pendant et après le script ?

theJB
WRInaute occasionnel
WRInaute occasionnel
 
Messages: 411
Inscription: 7 Avr 2006

Message le Jeu Juil 31, 2008 15:03

Voila comment je procede :
- je lance le script de parsing dans une fenetre
- je lance le script qui m'affiche la mémoire dans une autre

Avec top sous ssh, mon script n'occupe jamais plus de 3% de mémoire (sur la ligne associée à son processus), mais pourtant la mémoire (indiquée par les 1ères lignes, avec la charge CPU) se fait grignoter petit à petit jusqu'à presque 2Gb. Et ensuite, la mémoire n'est plus libérée.

Et je te confirme que mon script ne contient que ça.


Bool
WRInaute passionné
WRInaute passionné
 
Messages: 1290
Inscription: 26 Fév 2004

Message le Jeu Juil 31, 2008 15:07

Donc en gros tu es en train de me dire que le cache disque de l'OS fonctionne correctement, c'est ça ?

Petit exemple :
Code: Tout sélectionner
Mem:   1036252k total,   645564k used,   390688k free,     3572k buffers
Swap:   505912k total,      116k used,   505796k free,   219952k cached


Tu fais référence au champ correspondant à mon 645564k used ?
Et ton champ 219952k cached il ne serait pas "énorme" à tout hasard ?

Essayes plutôt un free -m :
Code: Tout sélectionner
             total       used       free     shared    buffers     cached
Mem:          1011        630        381          0          3        214
-/+ buffers/cache:        411        600
Swap:          494          0        493


La ligne "-/+ buffers/cache" indique les valeurs ajustées en tenant compte du cache et autres buffers. Soit dans mon cas 411Mo d'utilisation et non 630Mo.

theJB
WRInaute occasionnel
WRInaute occasionnel
 
Messages: 411
Inscription: 7 Avr 2006

Message le Jeu Juil 31, 2008 15:33

avant

Code: Tout sélectionner
top - 16:27:02 up 1 min,  1 user,  load average: 1.22, 0.40, 0.14
Tasks: 142 total,   1 running, 141 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   2061660k total,   314300k used,  1747360k free,     4532k buffers
Swap:   922600k total,        0k used,   922600k free,   114552k cached


Code: Tout sélectionner
             total       used       free     shared    buffers     cached
Mem:          2013        312       1700          0          4        113
-/+ buffers/cache:        194       1819
Swap:          900          0        900


Après

Code: Tout sélectionner
top - 16:31:19 up 5 min,  2 users,  load average: 0.63, 0.39, 0.17
Tasks: 150 total,   1 running, 149 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.2%us,  0.0%sy,  0.0%ni, 99.8%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   2061660k total,  1824116k used,   237544k free,     7256k buffers
Swap:   922600k total,        0k used,   922600k free,  1607212k cached


Code: Tout sélectionner
             total       used       free     shared    buffers     cached
Mem:          2013       1781        231          0          7       1569
-/+ buffers/cache:        204       1808
Swap:          900          0        900



Effectivement le cache est énorme. Qu'est-ce que cela signifie?


Bool
WRInaute passionné
WRInaute passionné
 
Messages: 1290
Inscription: 26 Fév 2004

Message le Jeu Juil 31, 2008 15:37

Bah rien d'anormal... c'est un cache disque. L'OS se sert de la mémoire non utilisée par les programmes pour conserver en mémoire une "copie du disque" ; ce qui lui permet d'accéder beaucoup moins souvent au disque.

Que ce soit avant ou après, tu n'as "que" 200Mo de mémoire utilisée.

Un peu de doc : http://fr.wikipedia.org/wiki/M%C3%A9moire_cache

theJB
WRInaute occasionnel
WRInaute occasionnel
 
Messages: 411
Inscription: 7 Avr 2006

Message le Jeu Juil 31, 2008 15:43

D'accord d'accord, j'ai donc passé mon aprèm sur un non-problème..

Petite question, la cache, elle se vide toute seule?

En tout cas merci du coup de main, j'y aurais passé ma semaine sans ton aide..
:)


Bool
WRInaute passionné
WRInaute passionné
 
Messages: 1290
Inscription: 26 Fév 2004

Message le Jeu Juil 31, 2008 15:48

Le cache n'a jamais vraiment besoin d'être "vidé". Si une application a besoin de mémoire, alors oui Linux libérera un peu de son cache pour l'application en question. Mais sinon il n'a aucune raison de vider le cache puisqu'il s'agit de mémoire qui n'est pas utilisée sinon.

C'est d'ailleurs pour ça que sous Linux (et probablement d'autres OS de nos jours) la mémoire est quasiment toujours utilisée intégralement.

Et de rien ;)


YoyoS
WRInaute accro
WRInaute accro
 
Messages: 3827
Inscription: 14 Sep 2006

Message le Jeu Juil 31, 2008 15:55

Oui ca sert à rien de vouloir vider la ram. Vaut mieux limite qu'elle se remplisse entièrement et que tu puisses avoir accès à tout ce qu'elle a en mémoire en une fraction de seconde. Si elle a besoin de mettre quelque chose en mémoire, soit le serveur dédié swap, soit elle efface les data les plus anciennes, ou les moins utilisés.

Il y a quelquechose à changer pour que le système favorise la ram par rapport au swap, mais je sais plus quoi :D Tout façon, je crois que c'est mis par défaut, faut pas s'inquiéter :)

Si tu utilises plus les 1.8go de la ram et que le systeme a besoin de mémoire libre, ne t'inquiète pas, il va les virer si ca fait des heures que c'est plus utilisé :D


Bool
WRInaute passionné
WRInaute passionné
 
Messages: 1290
Inscription: 26 Fév 2004

Message le Jeu Juil 31, 2008 15:59

Si tu utilises plus les 1.8go de la ram et que le systeme a besoin de mémoire libre, ne t'inquiète pas, il va les virer si ca fait des heures que c'est plus utilisé


Pourquoi diable effacerait il des données du cache s'il n'a pas besoin de la mémoire en question ? Cela ne servirait à rien, et serait susceptible de ralentir le système si quelques temps après les données sont à nouveau lues.

Le cache n'est nettoyé qu'en cas de "manque" de mémoire... et ce n'est certainement pas lui qui va déclencher le "swap", ce serait ridicule.

Script PHP : Problème de mémoire

Si vous avez aimé cette discussion, partagez-la sur vos réseaux sociaux préférés :

Formation recommandée sur ce thème :

Formation Google Analytics : en 2 jours, apprenez comment exploiter l'essentiel des possibilités de l'outil de mesure d'audience de Google. Formation animée par les experts Google Analytics de Ranking Metrics.

Tous les détails sur le site Ranking Metrics : programme, prix, dates et lieux, inscription en ligne.

Lectures recommandées sur ce thème :



Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 0 invités