IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Libération de mémoire


Sujet :

Langage PHP

  1. #1
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2007
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2007
    Messages : 241
    Points : 272
    Points
    272
    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

  2. #2
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    montre ton code

  3. #3
    Membre éprouvé Avatar de Marc3001
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2008
    Messages
    829
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2008
    Messages : 829
    Points : 1 275
    Points
    1 275
    Par défaut
    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

  4. #4
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2007
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2007
    Messages : 241
    Points : 272
    Points
    272
    Par défaut
    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

  5. #5
    Membre confirmé
    Avatar de FMaz
    Inscrit en
    Mars 2005
    Messages
    643
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 643
    Points : 640
    Points
    640
    Par défaut
    gc_enable() ?

    fait une analyse avec memory_get_peak_usage(), effectue un profilage de l'exécution.

  6. #6
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2007
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2007
    Messages : 241
    Points : 272
    Points
    272
    Par défaut
    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

  7. #7
    Membre éprouvé Avatar de Marc3001
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2008
    Messages
    829
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2008
    Messages : 829
    Points : 1 275
    Points
    1 275
    Par défaut
    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

  8. #8
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2007
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2007
    Messages : 241
    Points : 272
    Points
    272
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  9. #9
    Membre confirmé
    Avatar de FMaz
    Inscrit en
    Mars 2005
    Messages
    643
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 643
    Points : 640
    Points
    640
    Par défaut
    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)

  10. #10
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    fait un foreach pour parcourir ton array,

    sinon ça c'est faux
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $o = NULL; //-- unset($o); - comportement identique

  11. #11
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2007
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2007
    Messages : 241
    Points : 272
    Points
    272
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  12. #12
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    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 ?

  13. #13
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2007
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2007
    Messages : 241
    Points : 272
    Points
    272
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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

Discussions similaires

  1. Libération de mémoire non réservée (operator=)
    Par 84mickael dans le forum C++
    Réponses: 7
    Dernier message: 27/05/2006, 13h30
  2. Problème libération de mémoire?
    Par Bartuk dans le forum C
    Réponses: 7
    Dernier message: 28/12/2005, 17h20
  3. Libération de mémoire
    Par petitcoucou31 dans le forum Langage
    Réponses: 1
    Dernier message: 16/09/2005, 14h10
  4. [Debutant(e)]problème de libération de mémoire
    Par skywalker3 dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 10/02/2005, 17h38
  5. Réponses: 25
    Dernier message: 16/07/2003, 20h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo