Précédent   Forum des professionnels en informatique > PHP > Langage
Langage Forum sur le langage PHP, la POO, les conventions, la sécurité, etc. Avant de poster : FAQ Langage, toutes les FAQ PHP, cours langage et sources PHP
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 25/10/2011, 17h58   #1
Membre confirmé
 
Homme Benjamin Rouxel
Développeur informatique
Inscription : avril 2007
Messages : 238
Détails du profil
Informations personnelles :
Nom : Homme Benjamin Rouxel
Âge : 25
Localisation : France, Côtes d'Armor (Bretagne)

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : avril 2007
Messages : 238
Points : 228
Points : 228
Envoyer un message via MSN à psylox
Par défaut Libération de mémoire

Bonjour à tous,

Pour un client je dois réaliser une tache symfony dont voici les grandes lignes:
- parser un fichier XML à l'aide de SAX et placer le résultat dans un tableau
- parcourir le tableau afin de créer des objets symfony correspondant au model.

Sur le serveur de dev tout fonctionne parfaitement, par contre sur le serveur de test la mémoire ne semble pas se vider correctement à chaque tour de boucle du tableau. Pour mieux visualiser ce qui se passe --> ici

Les 2 serveurs tournent sous Debian 6.0, les versions de phps sont identiques: PHP 5.3.3-7+squeeze3. Les scripts PHP executés sur les 2machines sont identiques, etc ... Les configurations de symfony sont aussi identiques.

Moi et mes collègues ne savont plus ou chercher pour comprendre pourquoi dans un cas cela fonctionne et pas dans l'autre.

Si vous aviez des suggestions de verifications à effectuer je suis tout ouïe!!
N'hésitez pas à me demander d'éclaircir certains points si nécessaire.

Merci d'avance aux courageux pour leur aide
__________________
Linux because rebooting is just for adding medias
psylox est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/10/2011, 18h48   #2
Modérateur
 
Inscription : septembre 2010
Messages : 7 131
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 131
Points : 8 491
Points : 8 491
montre ton code
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 26/10/2011, 12h13   #3
Membre chevronné
 
Avatar de Marc3001
 
Homme
Ingénieur développement logiciels
Inscription : février 2008
Messages : 430
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 28
Localisation : France, Ille et Vilaine (Bretagne)

Informations professionnelles :
Activité : Ingénieur développement logiciels

Informations forums :
Inscription : février 2008
Messages : 430
Points : 682
Points : 682
C'est parceque ton serveur local est localisé à l'Est du méridien de GreenWich et l'hébergement à l'Ouest... C'est un bug connu sur Debian 6.0...

Sans code c'est chaud de deviner......
__________________
Le logiciel, c'est comme le sexe, c'est meilleur quand c'est libre.

Linus Torvalds
Marc3001 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/10/2011, 12h40   #4
Membre confirmé
 
Homme Benjamin Rouxel
Développeur informatique
Inscription : avril 2007
Messages : 238
Détails du profil
Informations personnelles :
Nom : Homme Benjamin Rouxel
Âge : 25
Localisation : France, Côtes d'Armor (Bretagne)

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : avril 2007
Messages : 238
Points : 228
Points : 228
Envoyer un message via MSN à psylox
Bonjour à vous,
Je ne vois pas en quoi fournir du code pourrait aider. Si cela venait effectivement de cette partie le problème de fuite se verrait sur les 2 serveurs.
De plus fournir mon code serait fastidieux étant donné le nombre de classes mises en cause.

L'aide que je demande concerne plus des points que je pourrai vérifier, plutot que de la correction de code.
Utilisant symfony (1.4) et doctrine (1.2), j'ai bien placé mes appels à free et unset. Vu tout ce que j'ai pu lire sur le net c'est que doctrine a des pbs de fuite et mémoire, et PDO aussi, d'ou une sur-consommation, mais la vraie question c'est COMMENT savoir pourquoi sur un serveur la mémoire est correctement libérée et pas sur l'autre serveur.

Qu'elles sont les options du php.ini qui peuvent être vérifiées/modifiées pour déterminer la raison de ce genre de pb etc ..

Ma question est-elle plus claire?
__________________
Linux because rebooting is just for adding medias
psylox est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/10/2011, 14h12   #5
Membre expérimenté
 
Avatar de FMaz
 
Inscription : mars 2005
Messages : 648
Détails du profil
Informations forums :
Inscription : mars 2005
Messages : 648
Points : 527
Points : 527
gc_enable() ?

fait une analyse avec memory_get_peak_usage(), effectue un profilage de l'exécution.
FMaz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/10/2011, 15h48   #6
Membre confirmé
 
Homme Benjamin Rouxel
Développeur informatique
Inscription : avril 2007
Messages : 238
Détails du profil
Informations personnelles :
Nom : Homme Benjamin Rouxel
Âge : 25
Localisation : France, Côtes d'Armor (Bretagne)

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : avril 2007
Messages : 238
Points : 228
Points : 228
Envoyer un message via MSN à psylox
Citation:
Envoyé par FMaz Voir le message
gc_enable() ?

fait une analyse avec memory_get_peak_usage(), effectue un profilage de l'exécution.
Citation:
Envoyé par psylox Voir le message
Pour mieux visualiser ce qui se passe --> ici
__________________
Linux because rebooting is just for adding medias
psylox est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/10/2011, 16h09   #7
Membre chevronné
 
Avatar de Marc3001
 
Homme
Ingénieur développement logiciels
Inscription : février 2008
Messages : 430
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 28
Localisation : France, Ille et Vilaine (Bretagne)

Informations professionnelles :
Activité : Ingénieur développement logiciels

Informations forums :
Inscription : février 2008
Messages : 430
Points : 682
Points : 682
Citation:
Envoyé par psylox Voir le message
Je ne vois pas en quoi fournir du code pourrait aider. Si cela venait effectivement de cette partie le problème de fuite se verrait sur les 2 serveurs.
Citation:
Envoyé par psylox Voir le message
Sur le serveur de dev tout fonctionne parfaitement, par contre sur le serveur de test la mémoire ne semble pas se vider correctement à chaque tour de boucle du tableau.
Si le problème de conso mémoire est identifié au niveau de cette boucle, donne le code de cette boucle histoire qu'on voit au moins de quoi ça a l'air....
__________________
Le logiciel, c'est comme le sexe, c'est meilleur quand c'est libre.

Linus Torvalds
Marc3001 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/10/2011, 17h11   #8
Membre confirmé
 
Homme Benjamin Rouxel
Développeur informatique
Inscription : avril 2007
Messages : 238
Détails du profil
Informations personnelles :
Nom : Homme Benjamin Rouxel
Âge : 25
Localisation : France, Côtes d'Armor (Bretagne)

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : avril 2007
Messages : 238
Points : 228
Points : 228
Envoyer un message via MSN à psylox
Le code suivant est donc une partie de la méthode execute d'une task symfony.
XmlToArray est une classe permettant depuis un fichier XML de récupérer un tableau décrivant le schema de "Objet" qui est un objet du model de la base de données. La méthode d'analyse XML utilisé est SAX, elle contient un destructeur qui libère bien les ressources du parseur.
La méthode free de Doctrine_Record a été surchargé par nos soins afin de terminer de libérer les données qui étaient encore stockées dans l'objet ...

Je ne sais que rajouter ?

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
$list = XmlToArray::parse(
	$xml, 
	$config
);
$this->logger->log($this->pid, 'End parsing : ' . number_format(memory_get_usage(), 0, '.', ',') . " octets", sfLogger::DEBUG);
$nb_obj_list = count($list);
for($i=0 ; $i < $nb_obj_list ; $i++) {
	$o = new Objet();
	$o->fromArray(array_pop($list), true);
	$o->save();
	$o->free(TRUE);
	$o = NULL; //-- unset($o); - comportement identique
	if(!($i % 1000))
		$this->logger->log($this->pid, 'Loop : ' . number_format(memory_get_usage(), 0, '.', ',') . " octets", sfLogger::DEBUG);
}
__________________
Linux because rebooting is just for adding medias
psylox est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/10/2011, 23h41   #9
Membre expérimenté
 
Avatar de FMaz
 
Inscription : mars 2005
Messages : 648
Détails du profil
Informations forums :
Inscription : mars 2005
Messages : 648
Points : 527
Points : 527
Ca va sembler ridicule, mais essaie ceci:

ne fait qu'instancier l'objet Object (vide), et que tu unset($o) ensuite, donc que tu n'accède à AUCUNE méthode de l'instance.

Est-ce que tu as toujours des statistiques de mémoire qui grimpe ?

Si oui;
Vérifie la configuration du garbage collector de PHP.

Sinon;
Montre-nous le code de Object ( Le constructeur, le destructeur, et la méthode free devrait suffire)
FMaz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/10/2011, 09h45   #10
Modérateur
 
Inscription : septembre 2010
Messages : 7 131
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 131
Points : 8 491
Points : 8 491
fait un foreach pour parcourir ton array,

sinon ça c'est faux
Code :
$o = NULL; //-- unset($o); - comportement identique
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/10/2011, 11h24   #11
Membre confirmé
 
Homme Benjamin Rouxel
Développeur informatique
Inscription : avril 2007
Messages : 238
Détails du profil
Informations personnelles :
Nom : Homme Benjamin Rouxel
Âge : 25
Localisation : France, Côtes d'Armor (Bretagne)

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : avril 2007
Messages : 238
Points : 228
Points : 228
Envoyer un message via MSN à psylox
Citation:
Envoyé par FMaz
ne fait qu'instancier l'objet Object (vide), et que tu unset($o) ensuite, donc que tu n'accède à AUCUNE méthode de l'instance.

Est-ce que tu as toujours des statistiques de mémoire qui grimpe ?

Si oui;
Vérifie la configuration du garbage collector de PHP.
Donc oui cela la mémoire continue de grimper, je vais donc regarder la configuration du GC

Citation:
Envoyé par stealth35
fait un foreach pour parcourir ton array,
Non pas de foreach à cause du scope des varialbles à l'interieur du bloc qui l'accompagne un foreach($list as $obj) me donnerai une copie de $list[$i] dans $obj et donc un unset($obj) de détruirai pas $list[$i].

Citation:
Envoyé par stealth35
sinon ça c'est faux
Code :
1
2
 
$o = NULL; //-- unset($o); - comportement identique
Je voulais dire que le comportement identique dans le cas qui m'interresse et non dans que "$o=NULL" est équivalent à "unset($o)"
__________________
Linux because rebooting is just for adding medias
psylox est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/10/2011, 11h29   #12
Modérateur
 
Inscription : septembre 2010
Messages : 7 131
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 131
Points : 8 491
Points : 8 491
Citation:
Envoyé par psylox Voir le message
Non pas de foreach à cause du scope des varialbles à l'interieur du bloc qui l'accompagne un foreach($list as $obj) me donnerai une copie de $list[$i] dans $obj et donc un unset($obj) de détruirai pas $list[$i].
tu le passer en référence, foreach($list as &$obj)mais de tout façon t'utilise pas le $list[$i]
sinon a quoi sert le XmlToArray sachant que tu peux parcourir un SimpleXMlElement ?
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/10/2011, 14h02   #13
Membre confirmé
 
Homme Benjamin Rouxel
Développeur informatique
Inscription : avril 2007
Messages : 238
Détails du profil
Informations personnelles :
Nom : Homme Benjamin Rouxel
Âge : 25
Localisation : France, Côtes d'Armor (Bretagne)

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : avril 2007
Messages : 238
Points : 228
Points : 228
Envoyer un message via MSN à psylox
Citation:
Envoyé par stealth35 Voir le message
tu le passer en référence, foreach($list as &$obj)mais de tout façon t'utilise pas le $list[$i]
sinon a quoi sert le XmlToArray sachant que tu peux parcourir un SimpleXMlElement ?
Oui j'utilise array_pop qui dépile l'élément de ma liste.

Pour XmlToArray, nous recevons un fichier XML d'un prestataire, nous devons stocker les données présentes dans ce fichier dans notre base de données, XmlToArray va créer un tableau correspondant à la structure de notre base en mappant les éléments XML vers nos tables et colonnes de la base via un fichier Yaml.

Sinon du coté du garbage collector, je n'ai pas trouvé beaucoup de moyen de le configurer a part les session.gc_*

Citation:
Envoyé par FMaz Voir le message
Sinon;
Montre-nous le code de Object ( Le constructeur, le destructeur, et la méthode free devrait suffire)
Il s'agit des constructeurs et destructeurs de la classe Doctrine_Record , et pour le free je l'ai surchargé pour rajouter la réinitialisation des attributs qui ne l'était pas.

Code :
1
2
3
4
5
6
7
8
9
10
11
 
public function free($deep = false) {
	parent::free($deep);
 
	$this->_values = array();
	$this->_modified = array();
	$this->_pendingDeletes = array();
	$this->_pendingUnlinks = array();
	$this->_lastModified = array();
	$this->clearInvokedSaveHooks();
}
__________________
Linux because rebooting is just for adding medias
psylox est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 08h42.


 
 
 
 
Partenaires

Hébergement Web