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érez notre mémoire.


Sujet :

Langage PHP

  1. #1
    Membre du Club
    Profil pro
    chef de projet
    Inscrit en
    Septembre 2008
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : chef de projet

    Informations forums :
    Inscription : Septembre 2008
    Messages : 43
    Points : 49
    Points
    49
    Par défaut libérez notre mémoire.
    Bonne nouvelle PHP5.3 ne souffre pas de la maladie d'Alzheimer
    Plus sérieusement je n'arrive pas à libérer la mémoire d'objets créés dans un tableau.
    Je joins ci-contre un exemple de code avec un tableau contenant des objets créés dynamiquement. Je n'arrive pas à récupérer la place mémoire occupée par les objets ( unset, $mavar=null ...).
    Dans la réalité j'emploie un code similaire dans un projet Symfony2 avec Doctrine pour mettre à jour une table à partir d'un fichier texte (100.000 lignes et plus ...). Le script PHP consomme toute la mémoire et échoue lamentablement.
    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
    17
    18
    19
    20
    21
    22
    23
     <?php
            class Objet {
                public $champs;
                public function __construct($init) {
                    $champs = $init;
                }
            }
            echo 'memoire initiale->' . memory_get_usage(true) . '<br/>';
            $tablo = array();
            for ($x = 0; $x < 1000; $x++) {
                $tablo[$x] = new Objet(str_repeat("Hello", 10000));
            }
            echo 'memoire après création tableau->' . memory_get_usage(true) . '<br/>';
            for ($x = 0; $x < 1000; $x++) {
                $mavar = $tablo[$x];
                $mavar = null;
                unset ($mavar);
                $tablo[$x] = null;
                unset($tablo[$x]);
            }
            $tablo = array();
            echo 'memoire après libération->' . memory_get_usage(true) . '<br/>';
            ?>
    Merci infiniment.

  2. #2
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Salut,

    pour forcer la passage du garbage collector, tu as à ta disposition gc_collect_cycles() après l'avoir activé avec gc_enable()

  3. #3
    Membre du Club
    Profil pro
    chef de projet
    Inscrit en
    Septembre 2008
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : chef de projet

    Informations forums :
    Inscription : Septembre 2008
    Messages : 43
    Points : 49
    Points
    49
    Par défaut Cela ne fonctionne pas avec gc_collect_cycles()
    Merci pour ton aide mais cela ne semble pas fonctionner.
    Le simple unset ne rend pas l'espace alloué par la création d'un objet PHP.
    Ai-je placé gc_collect_cycles() au bon endroit ?:
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
       <?php
            class Objet {
                public $champs;
                public function __construct($init) {
                    $champs = $init;
                }
     
            }
            echo 'memoire initiale->' . memory_get_usage(true) . '<br/>';
            gc_enable();  // GC_ ENABLE()
            $tablo = array();
            for ($x = 0; $x < 1000; $x++) {
                $tablo[$x] = new Objet(str_repeat("Hello", 10000));
            }
            echo 'memoire après création tableau->' . memory_get_usage(true) . '<br/>';
            for ($x = 0; $x < 1000; $x++) {
                $mavar = $tablo[$x];
                $mavar = null;
                unset ($mavar);
                $tablo[$x] = null;
                unset($tablo[$x]);
     
            }
     
            $tablo = array();
            echo gc_collect_cycles(). '<br/>'; // GC_COLLECT_CYCLES()
            echo 'memoire après libération->' . memory_get_usage(true) . '<br/>';
            ?>
    Pour mémoire affichage du programme :

    memoire initiale->524288
    memoire après création tableau->786432
    0
    memoire après libération->786432

  4. #4
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Le résultat que tu obtiens est tout à fait normal vu que tu as une erreur dans ton code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public function __construct($init) {
        $champs = $init;
    }
    devrait être
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public function __construct($init) {
        $this->champs = $init;
    }
    voici ce que j'obtiens :
    memoire initiale->524 288
    memoire après création tableau->52 953 088
    0
    memoire après libération->25 165 824
    
    Après il semblerait que tu sois assez limité sur les possibilités de manipulation la mémoire occupée par PHP...
    Comme tu peux le voir gc_collect_cycles() renvoie 0 références circulaires libérées, pour que tu aies un intérêt à l'utiliser, il faut être dans le cas des arborescences de classes je pense.

  5. #5
    Membre du Club
    Profil pro
    chef de projet
    Inscrit en
    Septembre 2008
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : chef de projet

    Informations forums :
    Inscription : Septembre 2008
    Messages : 43
    Points : 49
    Points
    49
    Par défaut le problème reste là
    Merci pour ta réponse !
    Le bon code est
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
     <?php
            class Objet {
                public $champs;
                public function __construct($init) {
                    $this->champs = $init;
                }
     
            }
            echo 'memoire initiale->' . memory_get_usage(true) . '<br/>';
            gc_enable();  // GC_ ENABLE()
            $tablo = array();
            for ($x = 0; $x < 1000; $x++) {
                $tablo[$x] = new Objet(str_repeat("Hello", 10000));
            }
            echo 'memoire après création tableau->' . memory_get_usage(true) . '<br/>';
            for ($x = 0; $x < 1000; $x++) {
                $mavar = $tablo[$x];
                $mavar = null;
                unset ($mavar);
                $tablo[$x] = null;
                unset($tablo[$x]);
     
            }
     
            $tablo = array();
            echo gc_collect_cycles(). '<br/>'; // GC_COLLECT_CYCLES()
            echo 'memoire après libération->' . memory_get_usage(true) . '<br/>';
            ?>
    et le résultat est
    memoire initiale->524288
    memoire après création tableau->52953088
    0
    memoire après libération->25165824

    Le problème reste entier et après le ménage (unset de toutes les variables) la mémoire devrait être égale ou proche de la mémoire intiale (la différence est de plus de 24 mégas).

Discussions similaires

  1. Réponses: 47
    Dernier message: 04/08/2011, 04h09
  2. fichier mappé en mémoire
    Par WinBernardo dans le forum Delphi
    Réponses: 7
    Dernier message: 01/12/2006, 09h38
  3. Déterminer l'adresse d'une application en mémoire
    Par Gib dans le forum x86 32-bits / 64-bits
    Réponses: 9
    Dernier message: 11/06/2002, 14h27
  4. Vitesse de la mémoire vidéo
    Par Anonymous dans le forum x86 16-bits
    Réponses: 3
    Dernier message: 06/06/2002, 20h20
  5. Problème avec la mémoire virtuelle
    Par Anonymous dans le forum CORBA
    Réponses: 13
    Dernier message: 16/04/2002, 16h10

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