JeuWeb - Crée ton jeu par navigateur
Objet vide = mémoire ?? WTF??? - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Objet vide = mémoire ?? WTF??? (/showthread.php?tid=5778)

Pages : 1 2


RE: Objet vide = mémoire ?? WTF??? - Sephi-Chan - 31-10-2011

Effectivement, ça n'a pas de sens. Hélas, on ne pourra pas t'aider sans le code de ta classe qui leak.


RE: Objet vide = mémoire ?? WTF??? - Wells - 02-11-2011

Voila le début de la class WSysteme (qui est bien plus longue)

Code :
class WSysteme extends WConnect
    {
    private $Id_Joueur;
    public $Id_JoueurID;
    public $Id_Systeme;
    public $SYJ_Galaxie;
    public $iTaxe;
    public $iStab;
    public $EtatStab;
    public $StabEvol;
    public $iDstCap;
    public $iEnv;
    public $Climat;
    public $SYJ_Taille;
    public $Politique;
    private $Politiques;
    public $PopActu;
    public $PopIdealBrut;
    private $PopIdeal;
    public $PopEvol;
    public $iPtPla;
    public $iScience;
    public $CoordX;
    public $CoordY;
    public $Nom_Systeme;
    public $Croi_Pop_Systeme;
    public $Capa_Dock;
    public $Zone_Race;

    public $ListeOBJ=array();
    public $ListeSTOCK=array();

    function __tostring() {return "Cette classe permet de manipuler la table systeme_joueur.";}

    //Fonction Get permetant le Lazy loading
    public function __get($property)
        {
        global $dbh;
        global $dbh;
        $valeur=$property.'ID';
        if(isset($this->$property))
            return $this->$property;
        elseif(isset($this->$valeur) and $property=='Id_Joueur')
            return new WJoueur($this->$valeur,$dbh);
        elseif(isset($this->Politique) and $property=='Politiques')
            return new WPolitique($this->Politique,$dbh);
        elseif($property=='PopIdeal')
            return $this->CalculePopIdeal($this,$dbh);
        else
            trigger_error('Impossible de charger le sous objet : '.$property);
        }

    //Constructeur
    function __construct($id,$connection=NULL)
        {
        $this->Load($id,$connection);
        }
        
    //Charge objet
    function Load($id,$connection=NULL)
        {
        if($id>0) {
        if($connection!='') $dbh = $connection;
        else $dbh = $this->CreerConnexionPDO();
        $requete = "SELECT * FROM systeme_joueur WHERE Id_Systeme='$id'";
        $stmt = $dbh->prepare($requete); $stmt->execute();
        foreach($stmt->fetchAll() as $data) {}

        $this->RemplitObjet($this,$data);
        }}

    //Créée une lise de systeme_joueur
    function GetListe($requete,$connection=NULL,$ordre='Id_Systeme')
        {
        if($connection!='') $dbh = $connection;
        else $dbh = $this->CreerConnexionPDO();
        $requete = "SELECT * FROM systeme_joueur WHERE $requete ORDER BY $ordre";
        $res = $dbh->query($requete);
        while($data = $res->fetch(PDO::FETCH_ASSOC))
            {
            $temp = new WSysteme();
            $temp->RemplitObjet($temp,$data);
            $this->ListeOBJ[$data['Id_Systeme']]=$temp;
            }
        }
        
    //Créée une lise de systeme pour le rapport
    function GetListeRapport($requete,$connection=NULL,$ordre='Id_Systeme')
        {
        if($connection!='') $dbh = $connection;
        else $dbh = $this->CreerConnexionPDO();
        $requete = "SELECT Id_Systeme,CoordX,CoordY,iEnv,Nom_Systeme,Climat,PopActu,Id_Joueur
        FROM systeme_joueur WHERE $requete ORDER BY $ordre";
        $res = $dbh->query($requete);
        while($data = $res->fetch(PDO::FETCH_ASSOC))
            {
            $temp = new WSysteme();
            $temp->RemplitObjet($temp,$data);
            $this->ListeOBJ[$data['Id_Systeme']]=$temp;
            }
        }
        
    //Remplit l'objet
    private function RemplitObjet(WSysteme $objet,$data)
        {
        $objet->Id_Joueur = NULL;
        $objet->Id_JoueurID = $data['Id_Joueur'];
        $objet->Id_Systeme = $data['Id_Systeme'];
        $objet->SYJ_Galaxie = $data['SYJ_Galaxie'];
        $objet->iTaxe = $data['iTaxe'];
        $objet->iStab = $data['iStab'];
        $objet->EtatStab = $data['EtatStab'];
        $objet->StabEvol = $data['SYJ_StabEvol'];
        $objet->iDstCap = $data['iDstCap'];
        $objet->iEnv = $data['iEnv'];
        $objet->Climat = $data['Climat'];
        $objet->SYJ_Taille = $data['SYJ_Taille'];
        $objet->Politique = $data['Politique'];
        $objet->PopActu = $data['PopActu'];
        $objet->PopIdealBrut = $data['PopIdeal'];
        $objet->PopEvol = $data['SYJ_PopEvol'];
        $objet->iPtPla = $data['iPtPla'];
        $objet->iScience = $data['iScience'];
        $objet->CoordX = $data['CoordX'];
        $objet->CoordY = $data['CoordY'];
        $objet->Nom_Systeme = stripslashes($data['Nom_Systeme']);
        $objet->Croi_Pop_Systeme = $data['Croi_Pop_Systeme'];
        $objet->Capa_Dock = $data['Capa_Dock'];
        $objet->Zone_Race = $data['Zone_Race'];
        }

Et voila le script appellant :

Code :
    echo '<br />Mémoire aprés recup données: '.round((memory_get_usage(FALSE)/1048576),2).' Mo';

//##################### SYSTEME DU JOUEUR ###########################
$LISTE_SYSTEME = new WSysteme;
$LISTE_SYSTEME->GetListeRapport("Id_Joueur='$login'",$dbh);
while(list($k,$SYSTEME)=each($LISTE_SYSTEME->ListeOBJ))
    {
    $Id_Systeme = $SYSTEME->Id_Systeme;
    $X = $SYSTEME->CoordX;
    $Y = $SYSTEME->CoordY;
    $iEnv = $SYSTEME->iEnv;    

    
    echo '<br>-->Mémoire sys joueur: '.round((memory_get_usage(FALSE)/1048576),2).' Mo';
    }
unset($LISTE_SYSTEME);
echo '<br><br>Mémoire apres sys joueur: '.round((memory_get_usage(FALSE)/1048576),2).' Mo';



RE: Objet vide = mémoire ?? WTF??? - Ter Rowan - 02-11-2011

salut j'ai une idée (mais suis un peu fatigué, alors ....)


ton instance de WSystem porte elle même des références à d'autres objets.

Quand tu "unset" WSystem, tu dois probablement supprimer l'instance (donc la liste des références) mais pas supprimer les instances des objets liés.

l'idéal, pour tester mon hypothèse est de créer un destructeur pour chaque classe qui fait juste echo 'je detruis l'objet XXX'

comme cela, on verra si la destruction a lieu après ou avant ta mesure de la mémoire (et donc de ton unset)


RE: Objet vide = mémoire ?? WTF??? - Sephi-Chan - 02-11-2011

Je penche aussi pour des instances qui ont toujours des références dans ton objet système.


RE: Objet vide = mémoire ?? WTF??? - Wells - 02-11-2011

En fait c'est l'inclusion de mes fichiers de class qui prend beaucoup de mémoire et qui n'est pas déchargeable. Est ce normal?


RE: Objet vide = mémoire ?? WTF??? - niahoo - 02-11-2011

Tu utilises les fonction d'autoload ?


RE: Objet vide = mémoire ?? WTF??? - Sephi-Chan - 02-11-2011

Ok, donc ce n'est rien de grave (dans la mesure où ça peut être conséquent mais limité en terme de quantité). Smile


RE: Objet vide = mémoire ?? WTF??? - Wells - 03-11-2011

Oui mais non. Car un fichier qui fait 50Ko sur mon DD, se transforme en 700Ko de mémoire. Le soucis c'est qu'une fois mes objets monter en mémoire, ca me prend plus de 25Mo.

Y a définitivement un truc que je comprend pas.


RE: Objet vide = mémoire ?? WTF??? - Ter Rowan - 03-11-2011

j'ai regardé un peu le code et y a deux trois trucs qui me paraissent peu pertinentes :

Citation :function GetListeRapport($requete,$connection=NULL,$ordre='Id_Systeme')
{
(...)
while($data = $res->fetch(PDO::FETCH_ASSOC))
{
$temp = new WSysteme();
$temp->RemplitObjet($temp,$data);
$this->ListeOBJ[$data['Id_Systeme']]=$temp;
}
}

//Remplit l'objet
private function RemplitObjet(WSysteme $objet,$data)
{
$objet->Id_Joueur = NULL;
$objet->Id_JoueurID = $data['Id_Joueur'];
(...)
$objet->Zone_Race = $data['Zone_Race'];
}
Tu passes en référence à une méthode de l'objet sa propre référence. Ca ne me semble vraiment pas pertinent et pas du tout correspondre à de la poo :


Citation :function GetListeRapport($requete,$connection=NULL,$ordre='Id_Systeme')
{
(...)
while($data = $res->fetch(PDO::FETCH_ASSOC))
{
$temp = new WSysteme();
$temp->RemplitObjet($data);
$this->ListeOBJ[$data['Id_Systeme']]=$temp;
}
}

//Remplit l'objet
private function RemplitObjet($data)
{
$this->Id_Joueur = NULL;
$this->Id_JoueurID = $data['Id_Joueur'];
(...)
$this->Zone_Race = $data['Zone_Race'];
}
(à noter tu as exactement le même problème dans __get avec CalculePopIdeal

Ensuite tu pourrais gagner énormément de volume de code avec plus de rigueur sur le nommage des champs et profiter pleinement de ta méthode get justement :

private function RemplitObjet($data)
{
$this->Id_Joueur = NULL;
$this->Id_JoueurID = $data['Id_Joueur'];
//(... vingtaine de lignes identiques ...)
$this->Zone_Race = $data['Zone_Race'];
}

Par

private function RemplitObjet($data)
{
foreach($data => $field as $value)
$this->$field = $value;

// et pour le cas special :
$this->Nom_Systeme = stripslashes($data['Nom_Systeme']);
}

après je ne sais pas pourquoi tu gonfles autant en mémoire, mais je me dis que tes auto références dans tous les sens (mon premier point) ne doit pas aider le garbage collector à vider la mémoire


RE: Objet vide = mémoire ?? WTF??? - niahoo - 03-11-2011

c'est ce que disais page précédente : attention aux ref circulaires.