Supprimer une instance correctement [AS3] - Flash/ActionScript - Programmation
Marsh Posté le 23-02-2010 à 15:45:01
Je ne pense pas que ça vienne de tes instances. Le Garbage Collector fonctionne pas trop mal. Et les displayList de AS3 ont apportées beaucoup de bonne chose pour ça.
Bref, je me souviens d'avoir fait des anims avec du code qui faisait des duplicateMovieClip en grande quantité (à l''époque d'AS2 donc).
Les trucs devaient tournés des mois sans s'arrêter sur des écrans dans un showroom. Et ben en soignant bien, j'avais aucune monté en charge.
Je pense donc que ton problème est issue de Away3D ... c'est lui qui doit garder un cache ou quelque chose. Cherche dans la doc, si il parle de cache, temp ou autre.
Sinon, essaie de te trouver des outils de debuggage qui puissent te dire exactement ce qui se passe dans ton anim ... surtout au niveau de la mémoire.
Marsh Posté le 23-02-2010 à 15:57:18
Je n'arrive pas à faire baisser les fps : quelle est la marche à suivre pour produire ce bug ? Ca a l'air de bien fonctionner chez moi
Marsh Posté le 23-02-2010 à 16:24:24
Fenston, va au 3eme niveau de ma galerie (pour ça, clique sur la 1ere vignette du 1er niveau, puis la 4eme du 2nd...)
clique sur une vignette pour zoomer dessus, puis retourne en arriere en cliquant dans le vide, puis rezoom, tu peux aussi cliquer sur les vignettes voisine une fois zoomé...
Bref, moi je commence à 16-17 fps (zoomé), et au bout d'une 10zaine de zoom/dézoom, je suis à 7 ...
Zed, en AS2, un simple delete suffisait... en AS3, tu dois mettre la valeur de l'objet à null, ce qui est sencé mettre l'objet dans le GC... Celui-ci ne le supprime pas forcément instantanément, mais c'est sensé être bien foutu à ce niveau...
Citation : In AS2, when you delete an object, the player pretty much grabs it, carries it to the incinerator, shoves it in and watches to make sure it’s completely destroyed. You delete it and it’s gone. |
Je pense pas qu'il s'agisse d'Away3D, mais plutôt de moi, je ne pige pas trop ce système de GC...
Je vais essayer de ne pas instancier moi même mon Clip (dans une variable), mais le creer directement dans la propriété material de mon plan...
Marsh Posté le 23-02-2010 à 16:52:52
J'ai réussis à reproduire le bug. J'ai eu du mal, mais effectivement, ça peut poser problème.
J'ignore comment résoudre ton problème de garbage collector, mais une façon de le contourner serait de preload tes galeries une fois au lancement au lieu de les charger à la volée à chaque fois.
Marsh Posté le 23-02-2010 à 18:56:43
Fenston a écrit : J'ai réussis à reproduire le bug. J'ai eu du mal, mais effectivement, ça peut poser problème. |
Euh... je ne vois pas le rapport...
Mon problème n'est pas lié au chargement d'un élément, mais d'en supprimer un pour de bon, qu'il arrête de titiller mon CPU alors qu'j'l'ai traité de null
Marsh Posté le 23-02-2010 à 19:03:25
Et t'as pas trouvé des blogs d'Indiens qui auraient trouvés une solution alternatives ou développé un code pour parer ça ?
Marsh Posté le 23-02-2010 à 19:20:46
Non, j'allais soumettre mon pb sur le forum support d'Away 3D, mais vu que ça me semblait plutôt être un problème de compréhension de l'AS3, c'était pas forcément une bonne idée... J'aimerais savoir si c'est un bug dejà, ou une erreur de ma part...
Marsh Posté le 23-02-2010 à 21:17:07
abais a écrit : |
J'avais mal compris ton problème. Je croyais que je soupçonnais le Garbage Collector de passer trop souvent alors que tu lui reproches de pas passer assez.
Le Garbage Collector libère la mémoire occupée par des objets qui n'ont plus de référence. C'est ce que tu fais avec var toto = null; Mais il y a d'autres cas de figure qui amènent un objet à ne plus avoir de référence : lorsque tu crées un objet en local dans une fonction sans garder de référence dessus en global.
Tu penses que le GC ne libère pas la mémoire à chaque fois que tu crées un objet et que tu lui supprimes sa référence. La solution, pour valider ta théorie, et est préloader des objets une fois en global au lancement de ton application, en les stockant par exemple dans un array. Par la suite, tu n'auras qu'à utiliser ces objets là plutôt que d'en créer de nouveaux à chaque fois que tu passes par la méthodes. Ainsi, t'es sur de garder une référence sur ton objet et de ne pas solliciter le garbage collector. Si ton application continue de ramer au bout d'un certain moment, c'est que tu as tort.
Perso, je pense pas que ça vienne de là. Ce genre de problème en général sont provoqué par deux choses :
- Les fuites mémoires
- Les timers qui bouclent sur eux même.
Utilises-tu des timers ? Si oui, es-tu sur et certain qu'ils ne continuent pas à agir malgré un cleartimeout ? J'ai déjà eu de mauvaises surprises à cause de ça...
Marsh Posté le 23-02-2010 à 23:18:09
Je n'utilise pas de timer...
Ce que tu dis est valable si c'est la création en soit de mes instances qui est lourde, mais ce n'est pas le cas...
Ce qui semble poser problème, c'est bien que le GC ne semble pas s'occuper de mes instance "nullifiée".
Sinon, je n'ose pas une seconde creer autant d'instance de mon clip autant qu'il y a d'images, c'est pas propres et c'est loin du concept de dynamisme que doit prendre ma galerie...
Des questions me viennent, si je met toto = null; est-ce que le fait que toto contiennent des enfants rendrait la mise dans le GC impossible ? Je dis ça parcequ'en ce moment, c'est ce que j'ai fais, comme vous pouvez le voir, mais je n'ai pas encore fais quoi que ce soit qui s'occupe de rendre null tous le contenu...
Je pense à ça vu que tu as l'air de sous entendre que le fait de laisser un Timer fouterait la merde...
S'assurer de rendre null tous les enfants/propriétés d'un objet pour à son tour le rendre null, ça peut paraitre logique, n'empêche que je trouve ça contraignant...
En même temps, c'est ce que j'ai fait pour les vignettes (quand un dossier se replie)
Enfain, ça m'étonne que Flash n'est pas prévu le coup... une fonction qui se charge de détruire un objet, s'occupant donc automatiquement de ses enfants/Listener etc...
Marsh Posté le 24-02-2010 à 00:02:02
abais a écrit : Je n'utilise pas de timer... |
- La solution de préload n'est pas incompatible avec la notion de dynamisme.
- La solution que je te propose n'est pas à considérer comme une solution définitive, mais plutôt comme un teste à faire te permettant de valider ou pas ta théorie.
Si tu mets toto=null alors l'objet n'a plus de référence. Il est donc inaccessible. Le garbage collector va donc s'en occuper et libérer l'espace mémoire. S'il y a des objets fils, ils seront de fait éliminés aussi. Si tu tentes par la suite d'appeler une fonction d'un objet fils, tu soulèveras une exception du genre "null pointer exception".
Si tu tentes de mettre à null un objet alors qu'il est utilisé, tu soulèveras aussi une exception.
D'où l'utilité des try catch Non seulement ca secure le code, mais aussi, et surtout, ça aide à voir où tu fais des erreurs quand tu debug
Pour ton problème, vu que t'utilises pas les timers, alors je penche comme Zed pour un problème de leak du coté de Away 3D.
Après, j'ai pas tout ton code sous le nez, si ça se trouve, ton problème est ailleurs et on regarde pas au bon endroit
Marsh Posté le 24-02-2010 à 00:03:42
Cherche dans les Frameworks je pense. Des fois j'utilise Guttershark et dedans y'a une classe pour mettre en cache et flush le cache. Je sais pas si ça fait ce que tu veux mais y doit bien y avoir des frameworks qui ont ce genre de fonctions ...
Marsh Posté le 24-02-2010 à 08:32:35
Attention !!! Quand tu fais monObjet = null, ce n'est pas l'objet que tu mets à null, mais la variable qui fait référence à cet objet.
(enfin c'est ce que je pense, mais si tu m'apporte la preuve du contraire).
Code :
|
ferait bien l'affaire nan.
PS : j'ai trouvé ça : http://blog.comtaste.com/2008/04/g [...] h_pla.html
Marsh Posté le 24-02-2010 à 08:36:07
Bon, j'ai soumis mon problème sur le forum de support Away3D...
J'espère qu'on comprendra mon anglais à chier...
Concernant le GC, j'ai lu assez de truc pour me convaincre que c'était assez bien foutu, donc je mets cette piste à l'écart...
J'ai toute mes raisons de penser que mon problème se situe dans ce que j'ai posté, vu que je ce sont les seules fonctions appelés pendant le test...
Il s'agit peut-être d'un problème d'Away3D, mais j'avoue que ça me dépasse...
Je vais faire en sorte que ce soit la même instance de mon movieClip qui fasse office de texture de toutes mes vignettes...
J'enfermerai dedans les fonctions qui se chargeront de s'updater entre 2 vignettes...
Marsh Posté le 24-02-2010 à 08:41:47
gatsu35 a écrit : Attention !!! Quand tu fais monObjet = null, ce n'est pas l'objet que tu mets à null, mais la variable qui fait référence à cet objet. un
|
J'avais essayer un delete, mais ça ne marche pas :
vignette3D.as(75): col: 11 Error: Attempt to delete the fixed property interactiveMC. Only dynamically defined properties can be deleted.
Ma variable est en effet déclaré au pied de ma déclaration de class...
J'avais cru lire qu'en AS3, un delete ne faisait pas plus qu'un "null"
Cependant quelque chose m'échappe... par dynamique, il entend que la variable soit déclaré au sein de ma fonction qui appelle le delete ?
gatsu35 a écrit : PS : j'ai trouvé ça : http://blog.comtaste.com/2008/04/g [...] h_pla.html |
Interessant ce qu'il dit sur les EventListener... je vais me pencher là dessus...
EDIT: Bon, j'ai mis les useWeakReference:Boolean à true; sur tous les addEventListener() de mes vignette3D
D'après l'article, c'est deja un bon pas vu que je recréé / effaces les vignette 3D à la volée...
Marsh Posté le 24-02-2010 à 09:55:54
abais a écrit : Je vais faire en sorte que ce soit la même instance de mon movieClip qui fasse office de texture de toutes mes vignettes... |
Je m'auto-quote pour dire que ça fonctionne à merveille ainsi, je peux avoir une petite baisse de FPS mais ça remonte aussi tôt...
J'ai donc une seule instance de mon clip (un SWC fait avec flash), j'ai pris soint de lui mettre une fonction "build()" qui lui permet de se construire, et une fonction autodestroy() qui permet d'etre "nettoyé" où il faut entre 2 zoom de vignette...
Bon, ça règle mon problème, mais je ne comprends toujours pas pourquoi ce qu'il se passait... Je suis apparemment naïf de croire qu'en "null-ifiant" un objet, le CPU s'en déchargerait (le GC gérant derrière)
Marsh Posté le 24-02-2010 à 10:31:55
abais a écrit :
|
Je pense que par dynamique, il veut dire que ta class doit être dynamique, de manière à pouvoir enlever et ajouter des propriétés facilement. (comme on pouvait le faire en AS2)
http://livedocs.adobe.com/flex/3/l [...] ml#dynamic
Sinon, bien joué pour ta solution ... c'est quand même un peu tordu (mais c'est pas de ta faute)
Marsh Posté le 24-02-2010 à 11:16:31
Zedlefou a écrit : |
En AS3, le template "dynamic" n'existe pas à la déclaration...
J'ai lu et relu à plusieurs endroit que "delete" ne s'utilisait pas en AS3...
Marsh Posté le 24-02-2010 à 11:17:28
Zedlefou a écrit : |
C'est assez dégueulasse d'avoir un objet dynamique et c'est consomateur
Marsh Posté le 24-02-2010 à 12:08:58
Merci en tout cas...
Je ne marque pas mon topic comme RESOLU car je considère que ça reste un mystère pour moi, mais je garde mon autre solution...
C'est la première fois que j'ai a supprimer des instances qui ne sont pas dans des conteneurs...
J'ai souvent eu à détruire des clips, le removeChild() (et le retrait des écouteurs dédiés) suffisait...
même lorsque qu'il s'agissait de particules que j'émettais/supprimais à la volé...
Ça m'a donc amené à une théorie : (j'aime bien faire des théories à 2 balles )
Le problème ici c'est justement qu'il n'y a pas d'addChild(), enfin, il y en a un forcément quelquepart mais c'est le framework Away3D qui s'en charge, moi je donne juste la class de mon clip à la création de mon MovieMaterial(clip:MovieClip)...
Je me suis donc re-re-re-plonger dans la doc d'Away3D et consulté toutes les methodes de cette class mais je n'ai rien trouvé...
Enfin bon, ça doit -etre un truc qui m'échape, un truc tout con si ça se trouve...
Si ma théorie était vrai, Away3D aurait ajouté une méthode pour palier ça...
Je fouillerais le setter de la class en question, de l'objet "movie"... En théorie, ils ont bien surement prévu de retirer le clip actuel avant d'en ajouter un autre... M'enfin...
Marsh Posté le 23-02-2010 à 14:41:49
Bonjour,
Je suis en train de faire mon site full flash...
Je m'éclate plutôt bien car j'apprends plein de truc, mais je rencontre un problème !
En AS3, supprimer une instance d'objet s'avère être particulier avec le Garbage Collector qui gère à sa manière !
Pour le moment, pour me débarrasser d'un element, j'efface ses écouteurs, je le retire avec removeChild si il s'agit d'un élément graphique, puis je lui applique la valeur "null"...
Le problème, c'est que ça ne semble pas fonctionner :
Dans la galerie site, quand on zoom sur une vignette, dé-zoom, puis rezoom etc..., On se rend compte rapidement que le taux de FPS chute constamment...
Tout me laisse donc penser que Flash garde en mémoire l'instance du clip qui fait office de texture à ma vignette zoomée...
Mon site : http://urfman.free.fr/fhw/ilotAbai [...] v2010.html (cliquez sur le cube pour lancer la galerie)
Ne vous étonnez pas si il y a que des plan rose ou vert, et qu'une fois zoomés, on vois juste un espece de cercle qui tourne, c'est encore en construction
La portion de code dédiée à l'activation/désactivation de map :
Pour info, cette portion est dans ma class de vignette 3D qui hérite de la classe Plane d'Away3D.
Pour mettre dans le contexte :
mapInteractive est un MovieMaterial (pour appliquer un MovieClip/Sprite en guise de texture sur un objet 3D)
vignetteSprite est mon clip en question, sa fonction buildMap lui permet de s'auto-construire si j'ose dire...
interactiveMC est l'instance de vignetteSprite...
mapLow est le material par defaut de ma vignette
Merci à tous ceux qui peuvent m'aider
---------------
Le membre ci-contre n'est pas responsable du message ci-dessus.