JeuWeb - Crée ton jeu par navigateur

Version complète : [PHP] Gestion de la mémoire
Vous consultez actuellement la version basse qualité d’un document. Voir la version complète avec le bon formatage.
Bonjour,

J'aurais aimer savoir - par curiosité - où trouver ou qu'on m'explique comment fonctionne la gestion de la mémoire du langage php.
En effet les types n'étant pas gérer au niveau du programmeur, comment cela fonctionne dans les couche inférieur?
L'allocation et la libération de la mémoire, les pointeurs, tout ça... comment ça fonctionne?

En gros: "Qui" le gère et comment?

Voilà, Merci.
Honnêtement, je me suis jamais penché la dessus. Si je programme en PHP, je me fous de savoir comment ça fonctionner derrière, si je veux du bas-niveau, ben je change de langage Smile

Après, je comprends ta curiosité Wink Le meilleur moyen, c'est de lire le code source de PHP :omg:

Je laisse les autres te répondre, parce qu'en plus le web fourmille pas de réponses... Peut-être ça : http://blog.pascal-martin.fr/post/php-5....on-memoire, et encore, c'est sur un point de détail.

Bye
A ce que je sache, php possède son garbage collector, enfin ça ne s'appelle pas comme ça en php mais le principe reste le même.
Peut être faut il allez voir du coté de L'ASCII ? Chaque caractère d'un script doit peser un certain nombre d'octet...
Je suis sûrement HS là mais bon... ^^
my hotel: oui c'est vraiment pour savoir s'il y aurait des "bonnes" pratiques en fonction de comment ça marche en dessous...
Kassak: c'est un peu plus compliquer que ça. ^^
Normalement pour gèrer les espaces mémoires, on met a chaque début de cases mémoires des informations sur celle-ci (taille, pointeur etc.)
Bah je ne m'y suis pas trop penché, mais comme la tous les langages non typé, c'est fait via des pointeurs. En fait, lorsque tu remplis ta variable en arrière le code détermine le type de ta variable et créer un int par exemple si tu mets 22. Ensuite, si tu change le contenu pour du texte la variable est supprimée et on crée une variable char [] (ou bien on utilise une librairie STL ou autre qui gère les chaines, mais déjà je pense que PHP à sa propre librairie de string).
Le lien de My Hotel dit le plus important, et il fourmille d'autres liens tout aussi intéressants, bien joué My Hotel Wink
[disclaimer]j'avais pas suivi le lien fourni par MyHotel, mais en fait je raconte la même chose que ce qu'ils disent là-bas. Par contre je ne suis pas d'accord sur le fait que c'est "un point de détail" même si ça ne concerne que des scripts un peu particuliers comme il est facile de s'en prémunir autant le faire Wink[/disclaimer]


Tout ce qu'il faut, c'est éviter les références croisées, et tu n'auras pas de problème.

En revanche, il faut faire bien attention de ne pas croire que ce type de code peut fonctionner ad vitam aeternam :
Code PHP :
<?php 
while (true) {
$variable = ...;
unset(
$variable);
}
Car justement avec les références croisées ça n'est plus vrai :
Code PHP :
<?php 
class A {
public
$b;
}
class
B {
public
$a;
}

while (
true) {
$a = new A();
$b = new B();
$a->b = $b;
$b->a = $a;
unset(
$a, $b); // on croit qu'on a libéré la mémoire, mais non !
// $a->b et $b->a sont perdus dans la nature, le garbage collector les a perdus, et la mémoire ne sera jamais libéré
} // "Fatal Error : Allowed memory size ..." garanti !

En reprenant l'exemple ci-dessus et en ajoutant une fonction __destruct() on se rend encore mieux compte de ce qui se passe, vous vous apercevrez que __destruct() n'est même pas appelé malgré l'unset !!
Comme $b embarque $a, lorsqu'on unset($a), il reste une référence vers l'objet ($b->a) et l'objet n'est donc pas détruit. Puis on essaie d'unset($b), mais comme $a n'a pas été détruit, il reste une référence vers l'objet ($a->b) et il n'est pas détruit non plus.
S'il n'y avait pas la référence croisée (mettons que $a->b n'existe pas) alors on aurait un scénario différent : j'essaie d'unset($a), ça ne détruit pas l'objet car il reste une référence vers l'instance en la personne de $b->a. Mais par contre au moment d'unset($b) là comme il n'y a plus de référence vers l'instance $b, l'objet est effectivement détruit, donc $b->a est unset, et comme c'était la dernière référence vers notre instance de A l'objet est enfin supprimé.

Cela peut être important de maîtriser ces concepts quand on a de gros calculs qui imposent la création d'un nombre important d'objets, ou tout simplement un script de type "daemon".
La seule règle à respecter est *pas de références circulaires* et tout ira bien Smile

Il parait que la 5.3 corrige en partie ça (mais comme ils ont une regression pourrie sur __toString(), je suis pas pret de l'adopter).

Et pour ceux qui pensent que ça ne viendrait à l'esprit de personne de faire ce type de référence croisée, ça vous semblera peut-être moins abstrait là :
Code PHP :
<?php 
class Personnage {
// un Personnage est contrôlé par un Joueur
public $proprietaire;
}
class
Joueur {
// un Joueur a un Personnage principal
public $personnage_principal;
}
Où là :
Code PHP :
<?php 
class Joueur {
// un Joueur a plusieurs Personnage
public $personnages;
}
class
Personnage {
// un Personnage est sur une Zone de la map
public $zone;
}
class
Zone {
// chaque Zone est contrôlée par un Joueur
public $joueur;
}
Ces exemples sont autant de causes potentielles de memory-leaks.