Optimisation code AS3 pour Garbage Collector

Résolu
Orange73 Messages postés 1375 Date d'inscription dimanche 28 novembre 2004 Statut Membre Dernière intervention 2 août 2011 - 23 oct. 2009 à 09:50
Twinspirit Messages postés 58 Date d'inscription mercredi 21 mai 2008 Statut Membre Dernière intervention 7 mai 2012 - 14 nov. 2009 à 17:13
Hello,

J'aurai juste quelques question afin d'optimiser mon code AS3 pour le passage du Garbage Collector.

1/ Imaginons une classe :
package 
{
     import flash.events.*;
     public MyClass extends Movieclip()
     {
          private var myClip:Sprite;
          public function MyClass()
          {
               myClip = new Sprite();
               addChild(myClip);
               myClip.addEventListener(MouseEvent.CLICK, clicking);
          }
     }
}


Puis une instanciation

import MyClass;
var o:MyClass = new MyClass();
addChild(o);


Si je fais un removeChild(o) puis un o = null, dois-je au préalable appeler une fonction dans ma classe MyClass qui fera :

removeChild(myClip)
removeEventListener(MouseEvent.CLICK, clicking)
myClip = null


???

Ou le fait de faire un removeChild() de l'instance de mon objet suffit ?

Merci

-- Orange73 --

"L'homme n'est pas fait pour travailler, la preuve c'est que cela le fatigue" (Voltaire)
A voir également:

42 réponses

Twinspirit Messages postés 58 Date d'inscription mercredi 21 mai 2008 Statut Membre Dernière intervention 7 mai 2012
4 nov. 2009 à 21:29
En ce qui me concerne, je ferai comme ca :

package 
{
     import flash.events.*;
     public MyClass extends Movieclip()
     {
          private var myClip:Sprite;
          
          public function MyClass()
          {
               this.addEventListener(Event.ADDED_TO_STAGE, active);
          }
          private function active(evt:Event):void
          {
               this.addEventListener(Event.REMOVED_FROM_STAGE, destruct);
               myClip = new Sprite();
               addChild(myClip);
               myClip.addEventListener(MouseEvent.CLICK, clicking);
          }
          private function destruct(evt:Event):void
          {
               this.removeEventListener(Event.ADDED_TO_STAGE, active);
               this.removeEventListener(Event.REMOVED_FROM_STAGE, destruct);
               myClip.removeEventListener(MouseEvent.CLICK, clicking);
               myClip = null;
          }
     }
}


pas besoin de faire un removeChild(myClip) : il disparait de la liste d'affichage avec myclass si myclass disparait. (si tu jetes une boite, tu jete aussi le contenu de la boite, non ?)

TwFlash - Développeur ActionScript3 freelance.
Mon blog : Twin Flash Blog
Mon site : TwFlash
3
Twinspirit Messages postés 58 Date d'inscription mercredi 21 mai 2008 Statut Membre Dernière intervention 7 mai 2012
6 nov. 2009 à 17:06
Toujours d'après mes tests (il me semble les faire dans de bonnes conditions)

un passage à =null d'une variable contenant une classe d'affichage, sans faire de removeChild ne libère pas de mé
moire. 


un removeChild() d'une classe sans faire passer les autres variables de la classe à null libère la mémoire.

MAIS ceci n'est valable que si ces variables, celles qui sont à l'intérieur de la classe que l'on veut enlever, ne sont pas utilisées en dehors de la classe.

par exemple : si le rectangle dans Testeur est une variable publique, et que dans la classe de document (celle qui contient Testeur) il y a une variable qui pointe dessus :
var myRect = Testeur.rectangle; 


Le rectangle restera en mémoire, même s'il disparait de la liste d'affichage. Il sera effacé dela mémoire si
myRect = null;


en fait, le GC compte lors de son passage le nombre de références à un objet. Si ce nombre est zero, l'objet est enlevé. Si c'est un objet d'affichage, il doit être removeChild.

Et un objet d'affichage est "removed" si son conteneur est removed et qu'il n'y a plus de références pointant sur lui, et ce sans besoin de faire de removeChild spécifiquement sur lui (comme dans mon rectangle).

Voici un lien voisin de celui que tu as donné qui explique cela mieux que moi, orange : [http://www.flex-tutorial.fr/2008/12/07/flex-debug-garbage-collector-as3-et-flash-player-9/ [lien]]

Faire ses propres tests avec le profileur de flex m'a beaucoup fait avancer sur le sujet. Je le conseille.

TwFlash - Développeur ActionScript3 freelance.
Mon blog : Twin Flash Blog
Mon site : TwFlash
3
pegase31 Messages postés 6138 Date d'inscription dimanche 21 décembre 2003 Statut Modérateur Dernière intervention 4 septembre 2013 12
23 oct. 2009 à 11:51
Bonjour

Il faut effectivement virer tout les écouteurs inhérents a la classe. Pour celà il existe un évènement "Removed_From_Stage" qui peut être utile.

Peg'
0
Orange73 Messages postés 1375 Date d'inscription dimanche 28 novembre 2004 Statut Membre Dernière intervention 2 août 2011
23 oct. 2009 à 12:19
Ok merci.

Mais si je fais un

removeChild(o);


je n'ai pas besoin de faire un

removeChild(myClip) 


dans la classe car forcement si je vire l'instance sur le stage, les instance dans mon objet sont automatiquement virer, non ?


removeChild(o);


mon objet est retiré de la scene


-- Orange73 --

"L'homme n'est pas fait pour travailler, la preuve c'est que cela le fatigue" (Voltaire)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
pegase31 Messages postés 6138 Date d'inscription dimanche 21 décembre 2003 Statut Modérateur Dernière intervention 4 septembre 2013 12
23 oct. 2009 à 12:55
De la scène, oui, mais pas de la mémoire ...
Et si un evènement se passe encore dans le clip, il ne sera pas retiré de la mémoire pour autant. Même avec un "null" à la place.

Peg'
0
samsam69003 Messages postés 12 Date d'inscription dimanche 18 octobre 2009 Statut Membre Dernière intervention 24 octobre 2009
24 oct. 2009 à 05:07
il faudrait regarder le livre de Mr Thibault Imbert sur le sujet .. (si quelqu'un arrive à comprendre... (déssssolé , mais j'ai du mal pour ma part . )
> http://pratiqueactionscript3.bytearray.org/?page_id4

vers le début du livre il traite le sujet , l'auteur maitrise le sujet .
0
Twinspirit Messages postés 58 Date d'inscription mercredi 21 mai 2008 Statut Membre Dernière intervention 7 mai 2012
28 oct. 2009 à 06:21
J'essaie de toujours rédiger mes functions comme suit :
package
{
//imports
public class myClass extends Sprite //par exemple
{
//declarations variables
public function myClass()
{
this.addEventListener(Event.ADDED_TO_STAGE, initialize);
}

public function initialize(evt:Event)
{
this.addEventListener(Event.REMOVED_FROM_STAGE, destruct);
}

public function destruct(evt:Event)
{
this.removeEventListener(Event.REMOVED_FROM_STAGE, destruct);
this.removeEventListener(Event.ADDED_TO_STAGE, initialize);
//et remove de tout autre listener en ecoute dans la classe
}
}
}


C'est ce que préconise T.Imbert, je crois.

TwFlash - Développeur ActionScript3 freelance.
Mon blog : Twin Flash Blog
Mon site : TwFlash
0
zen69 Messages postés 584 Date d'inscription jeudi 28 décembre 2006 Statut Membre Dernière intervention 29 avril 2010 1
28 oct. 2009 à 14:37
Twinspirit, jolie ce code!


---------------------------------------------------------
Julien B.
0
Orange73 Messages postés 1375 Date d'inscription dimanche 28 novembre 2004 Statut Membre Dernière intervention 2 août 2011
2 nov. 2009 à 23:47
Merci :)

et si je remplace le addChild() dans ma classe :

public function MyClass()
{
myClip = new Sprite();
addChild(myClip);
myClip.addEventListener(MouseEvent.CLICK, clicking);
}

par

...
// clipContainer est un clip présent sur la scène.
clipContainer.addChild(myClip);
...

Dois-je faire un removeChild du clip "myClip" dans "clipContainer" dès que je removeChild l'instance de ma classe afin de permettre le passage du garbage collector ?


-- Orange73 --

"L'homme n'est pas fait pour travailler, la preuve c'est que cela le fatigue" (Voltaire)
0
Twinspirit Messages postés 58 Date d'inscription mercredi 21 mai 2008 Statut Membre Dernière intervention 7 mai 2012
3 nov. 2009 à 00:34
Si dans ta classe d'affichage, tu as bien prévu une fonction de désactivation en cas de retrait de l'objet de la scène (la function destruct dans mon code plus haut, par exemple), celle-ci sera activée en cas de retrait de l'objet ou du conteneur de l'objet.

Les écouteurs contractés par myClip seront automatiquement désactivés en interne grâce à la fonction destruct... myClip devrait être eligible au garbage collector. (sous réserve qu'aucune variable ne pointe sur lui et qu'aucun écouteur n'ai été contracté en externe.)

TwFlash - Développeur ActionScript3 freelance.
Mon blog : Twin Flash Blog
Mon site : TwFlash
0
Orange73 Messages postés 1375 Date d'inscription dimanche 28 novembre 2004 Statut Membre Dernière intervention 2 août 2011
4 nov. 2009 à 19:36
Donc pas besoin de faire un removeChild de myClip dans la classe ? ni de le mettre a null ? mais simplement virer les evenements ?


-- Orange73 --

"L'homme n'est pas fait pour travailler, la preuve c'est que cela le fatigue" (Voltaire)
0
Twinspirit Messages postés 58 Date d'inscription mercredi 21 mai 2008 Statut Membre Dernière intervention 7 mai 2012
4 nov. 2009 à 19:47
si myclip est défini dans une variable du constructeur de la classe,
par exemple :
private var myclass:MovieClip;


tu dois la passer à null.
Si elle n'existe que dans une fonction, ce n'est pas la peine, virer les ecouteurs devrait suffire.

TwFlash - Développeur ActionScript3 freelance.
Mon blog : Twin Flash Blog
Mon site : TwFlash
0
pegase31 Messages postés 6138 Date d'inscription dimanche 21 décembre 2003 Statut Modérateur Dernière intervention 4 septembre 2013 12
4 nov. 2009 à 20:07
donc si un sprite (par exemple) est construit dans une fonction et qu'il fait partie de la liste d'affichage d'un displayObject, s'il n'a aucun écouteur, le garbage collectir le vire ?

Pas mal celle-là ..

Peg'
0
Twinspirit Messages postés 58 Date d'inscription mercredi 21 mai 2008 Statut Membre Dernière intervention 7 mai 2012
4 nov. 2009 à 20:50
Il le vire si le displayObject qui le contient disparait de la liste d'affichage, qu'aucune variable ne le contient, qu'aucun écouteur n'est lié à lui en externe et qu'il gère lui même la désactivation de ses écouteurs en interne.

Oui ? Non ?

TwFlash - Développeur ActionScript3 freelance.
Mon blog : Twin Flash Blog
Mon site : TwFlash
0
Orange73 Messages postés 1375 Date d'inscription dimanche 28 novembre 2004 Statut Membre Dernière intervention 2 août 2011
4 nov. 2009 à 20:55
Imaginons de nouveau ceci :

package 
{
     import flash.events.*;
     public MyClass extends Movieclip()
     {
          private var myClip:Sprite;
          public function MyClass()
          {
               myClip = new Sprite();
               addChild(myClip);
               myClip.addEventListener(MouseEvent.CLICK, clicking);
          }
     }
}


Comment l'optimiser pour permettre le GC ?
sachant qu'on a sur le stage une instance de cette classe + addChild de celle ci.


-- Orange73 --

"L'homme n'est pas fait pour travailler, la preuve c'est que cela le fatigue" (Voltaire)
0
pegase31 Messages postés 6138 Date d'inscription dimanche 21 décembre 2003 Statut Modérateur Dernière intervention 4 septembre 2013 12
4 nov. 2009 à 21:15
il y a 3 choses qui font qu'un DisplayObject soit supprimé :

- qu'il n'ai plus aucun process en cours d'exécution (écouteur, timer, tween, etc...)
- qu'il n'appartienne à aucune liste d'affichage
- qu'il ne soit pas instancié dans une classe active (une qui ne respecte pas ces 3 critères)

Peg'
0
Orange73 Messages postés 1375 Date d'inscription dimanche 28 novembre 2004 Statut Membre Dernière intervention 2 août 2011
4 nov. 2009 à 21:23
Ok, donc dans mon exemple je dois creer une fonction de ce style :

private function dispose():Void
{
    removeChild(myClip);
    myClip.removeEventListener(MouseEvent.CLICK, clicking);
    myClip = null;  
}


Par contre je ne suis pas sur que je dois faire un removeChild de myClip car un removeChild de l'instance de ma class sur le stage par exemple ne suffit t'il pas ?

-- Orange73 --

"L'homme n'est pas fait pour travailler, la preuve c'est que cela le fatigue" (Voltaire)
0
pegase31 Messages postés 6138 Date d'inscription dimanche 21 décembre 2003 Statut Modérateur Dernière intervention 4 septembre 2013 12
4 nov. 2009 à 21:33
sauf si le contenu de ta boîte ne peut pas être "jeté" ...

Peg'
0
Orange73 Messages postés 1375 Date d'inscription dimanche 28 novembre 2004 Statut Membre Dernière intervention 2 août 2011
4 nov. 2009 à 21:35
Ok cool merci ;-)

Par contre, c'est exacte pour la boite ;) dommage qu'on arrive pas a la jetter tant que le contenu est animé/bouge !

a=

-- Orange73 --

"L'homme n'est pas fait pour travailler, la preuve c'est que cela le fatigue" (Voltaire)
0
Orange73 Messages postés 1375 Date d'inscription dimanche 28 novembre 2004 Statut Membre Dernière intervention 2 août 2011
4 nov. 2009 à 21:38
sauf si le contenu de ta boîte ne peut pas être "jeté" ...


Peg' qu'entend tu par là ? tu parle si il y a des events sur les displayObject présent dans la classe ?


-- Orange73 --

"L'homme n'est pas fait pour travailler, la preuve c'est que cela le fatigue" (Voltaire)
0
Rejoignez-nous