Forums Développement Multimédia

Aller au contenu

- - - - -

as2 garbage collector : bmp et perte de mémoire

as2 CODE PAO

5 réponses à ce sujet

#1 trstn

    Ceinture Blanche

  • Members
  • Pip
  • 7 messages

Posté 28 August 2014 - 11:44 AM

Bonjour flasheurs/euses,

Je viens solliciter votre soutien, je ne trouve pas de solution pour purger la mémoire ram pendant la lecture de mon appli flash. Tout tuyau serait bienvenue.

J'aimerais un quelque chose qui ressemble à (removeMovieClip(); + .dispose(); + valeur=null) :ph34r:

A mesure que mon animation charge des données, la mémoire utilisée augmente, de façon "raisonnable", c'est-à-dire cohérente, mais ne s'arrête jamais (jusque 250Mo...), et rien ne se décharge en allant.

Pour être clair :

J'ai un grand nombre de bmps importés, un trop grand nombre pour pouvoir les attachBitmap chacun dans une variable. Je crois que ca alourdirait beaucoup(?).
Cela rend donc le .dispose(); impossible je crois (ou alors je m'y prends mal, je ne connais pas la syntaxe pour disposer(); le contenu d'un clip, voire un clip lui-même. Je n'ai trouvé que son application au contenu d'une variable).

J'ai donc mis mes bmps dans différentes keyframes de Movieclips puis : removeLemovieclipenquestion(); + =null;

Ca ne change rien. Le garbage collector peut (si j'ai rien oublié) garbager, mais ne le fera que si cela lui semble nécessaire. Donc... j'ai lancé plein de softs histoire de faire travailler ma ram (oui oui je sais) j'ouvre le taskmanager de windows et là-dessus je fais tourner mon anim. Il faut croire que la ram n'était pas suffisament sollicitée car le garbage collector continuait de se curer le nez.

Où plutôt, le removemovieclip; + =null; n'a aucune incidence sur les pixels stockés...

Voici où j'en suis.

Il existe des "parties" dans mon anim, plus ou moins équivalentes à des levels dans un jeu. Aussi, quand on est dans le level2, on n'a pas réellement besoin que le level1 soit gardé en mémoire. L'idéal serait, plutôt que d'essayer de virer mes bmps en allant et d'avaler des ressources continuellement (quoique je ne sois pas contre une solution de ce type si ca peut s'optimiser), de 'delete' le level1 de la mémoire lorsque l'on passe au level2. Rien ne les relie, et on ne peut de toute façon plus y revenir. Donc laisser s'agglutiner les données de la partie 1, jusqu'une 50aine de Mo max, fouit' on vire tout ça en arrivant au level2 et retour à 0 on passe à la suite.

Peut-être serait-il judicieux de penser carrément à un appel de swf externes à charger/décharger au fur et à mesure, mais cela permettrait-il de libérer la mémoire bloquée par les bmps?

(ps: j'ai la preuve que c'est les bmps qui mangent tout)

Merci beaucoup de votre coup de main!

#2 trstn

    Ceinture Blanche

  • Members
  • Pip
  • 7 messages

Posté 28 August 2014 - 16:05 PM

Appeler différents fichiers swf depuis un "fichier chargeur" est en effet une solution, car dans ce cas de figure, unload(); detruit véritablement l'objet et la mémoire est ainsi soulagée.

L'animation est censée se jouer en standalone, aussi c'est un peu contrariant d'avoir à distribuer un zip contenant 10 ou 12 fichiers au lieu d'1.

Autre aspect négatif, si je souhaite monter un executable via zinc de ce machin là (un chargeur + des swf appelés successivement par ce chargeur) retour au problème initial, la mémoire n'est pas libérée au moment d'enlever la partie qui vient de se jouer pour lancer la suivante :mellow:.

Si vous êtes inspirés... :D

#3 dldler

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 4163 messages

Posté 28 August 2014 - 17:10 PM

Bonjour trstn.

Si j'ai bien compris, tu as un fichier Flash, avec une bibliothèque pleine de BMP.
Tu compiles un swf unique, donc qui contient tout.
Ce fichier, quand il s'ouvre, ouvre évidemment tous les BMP de la bibliothèque… impossible de faire autrement dans ce cas. Il n'y a que la fragmentation en fichiers séparés qui permette de loader/unloader.
Par contre, si tu ouvres le fichier swf, la mémoire occupée dès le départ ne devrait pas trop gonfler ensuite. Les occurrences de BMP sont plutôt bien gérés par Flash, qui différencie les conteneurs : Bitmap, et les données : Bitmapdata. Si tu gères bien, tu ne dois toujours créer qu'un bitmapdata, que tu peux afficher dans autant de bitmap que tu veux. En gérant ainsi, ça va gonfler la mémoire pour le calcul du rendu video, mais c'est tout. Dès qu'un truc n'est plus affiché, il ne consomme plus de mémoire (ou très très peu).

En gros, et puisque tu n'as qu'un seul fichier swf, si la mémoire occupée est importante mais plutôt stable : c'est normal.
Mais si la mémoire utilisée augmente de façon régulière et significative, c'est que tu as une fuite.

Concernant les fuites : perso, je ne crois pas trop aux méthodes de .release, .unload, .purge et autres joyeusetés. Elles sont aux mieux consommatrices de mémoire, au pire : contreproductives.
Je crois d'avantage à l'effondrement pyramidal : si tu utilises un conteneur général (typiquement un Sprite nommé "niveau"), il te suffit de désaffecter le niveau et lui seul avec un removeChild (niveau); puis d'en créer un nouveau : niveau = new Niveau_2(); et enfin d'afficher le nouveau niveau : addChild (niveau).

Idem pour les personnages et éléments : si tu les stockes dans un seul tableau (par exemple tableau_elements), quand tu changes de niveau, reinitialise ton tableau principal : tableau_elements = []; et ça doit suffire.
Dans la pratique, je crois que je n'ai jamais eu de fuites de mémoire, d'autres en ont parfois. C'est sans doute dû à la structure d'ensemble plutôt qu'au détail des movieclip.

Un turc que je surveillerais de près : les enfants ne doivent jamais-jamais manipuler leurs parents. Ça, oui, ça peut provoquer des fuites parce que ça empêche le GC de supprimer les parents, puisqu'ils ont toujours un lien actif venant de leurs enfants, même si ceux-ci ne sont plus retenus.

A propos du GC (garage collecter) : il ne s'occupe pas vraiment de ce que tu fais sous Windows. Il s'occupe uniquement de la mémoire allouée au swf. Il passe principalement quand le swf demande un nouveau bloc mémoire (généralement une instantiation d'un nouvel objet). Le gc fait le ménage dans la mémoire utilisée par le swf.
1 - S'il dégage un bloc suffisant pour l'instantiation, il s'en sert. Il regarde le reste de la mémoire libérée, en garde ce qui lui semble nécessaire sous le coude, libère le reste vers le system.
2 - Sinon, il demande un nouveau bloc au system et en attribue le morceau nécessaire à l'instantiation puis il garde le reste sous le coude.

Cas concret si on reprend l'exemple d'un movieclip niveau_1 affiché : il vaudrait mieux libérer le niveau_1 avant de créer le niveau_2 pour que la mémoire du _1 puisse être refourguée au _2. Sinon, elle ne le sera qu'à la prochaine grosse instantiation, probablement le niveau_3…

#4 trstn

    Ceinture Blanche

  • Members
  • Pip
  • 7 messages

Posté 28 August 2014 - 19:11 PM

Bonjour dIdIer,

Merci pour ta dense réponse c'est chouette.
Tu as bien compris mon problème. Ma bibliothèque est pleine à craquer et en effet les choses semblent bien prévues.

Mais

Voir le messagedldler, le 28 August 2014 - 17:10 PM, dit :

Par contre, si tu ouvres le fichier swf, la mémoire occupée dès le départ ne devrait pas trop gonfler ensuite. Les occurrences de BMP sont plutôt bien gérés par Flash, qui différencie les conteneurs : Bitmap, et les données : Bitmapdata. Si tu gères bien, tu ne dois toujours créer qu'un bitmapdata, que tu peux afficher dans autant de bitmap que tu veux.

Ça je bloque un peu. Je ne sais pas comment le gérer. Pour être honnête à propos du bazar que j'ai mis, j'ai des "anims bitmaps" un peu partout :idea: . Autrement dit il m'arrive d'avoir, plutôt que des interpolations vectorielles, des ensembles d'images bmp qui tournent en boucle (formes complexes en noir et blanc dans les 25ko chacune). Est-il envisageable de créer un unique conteneur bitmap et d'en changer dynamiquement le contenu a chaque frame (12/sec)? Ou bien de créer autant de conteneurs que d'images (Une 20aine), de les dispatcher sur les frames puis de changer le contenu de chacun d'eux lorsque je change de plan?
Je partais du principe que ca allait labourer tout le long et n'ai pas essayé...

Pour la fuite je ne pense pas, la mémoire utilisée augmente de facon proportionnelle à chaque affichage de bmp, oui, mais s'arrete une fois que ceux-ci se sont affichés au moins une fois (ca ne bouge plus si on y revient).

Pour le gc, je pensais l'inciter un peu à passer me voir en occupant la mémoire qu'il convoiterait au fur et à mesure du chargement des bmps. Je ne m'y tromperai plus :mrgreen: .

Pour le reste, je prends note merci de m'éclairer.

#5 dldler

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 4163 messages

Posté 28 August 2014 - 20:50 PM

Fais une recherche à propos de sprite
Attention, le terme a un double sens.
En as : C'est un conteneur de type graphique, très léger, sans scénario.
En programmation de jeux vidéo, c'est un bmp contenant plusieurs images d'une animation.
Les deux sens t'intéressent... Et tout le monde dit que c'est efficace et rapide. Bien plus que des images séparées dans un movieclip.

Ps : Je viens de voir que ton sujet parle d' as2.
Si ce n'est pas une erreur, c'est dommage.
As3 est beaucoup plus efficace et permet une bien meilleure gestion de la mémoire.
Vu ce que tu essayes de faire, ce serait un gros plus de faire l'effort.
En plus, je crois que le conteneur Srite n'existe pas en as2

#6 trstn

    Ceinture Blanche

  • Members
  • Pip
  • 7 messages

Posté 28 August 2014 - 21:00 PM

Ok je vais jeter un zyeux sur tout ça.
Merci d'avoir infirmé/confirmé certaines hypothèses et de m'avoir aiguillé pour que j'y voie plus clair.
Je vais essayer et voir comment optimiser au mieux.
A plus tard




Répondre à ce sujet



  

1 utilisateur(s) li(sen)t ce sujet

0 membre(s), 1 invité(s), 0 utilisateur(s) anonyme(s)