IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

ActionScript 3 Discussion :

AS3 : liberation de la mémoire avec la classe Loader en chargeant des Bitmap


Sujet :

ActionScript 3

  1. #1
    Membre expérimenté Avatar de Lorenzo77
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    1 472
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2006
    Messages : 1 472
    Points : 1 537
    Points
    1 537
    Par défaut AS3 : liberation de la mémoire avec la classe Loader en chargeant des Bitmap
    salut les gars,

    j'ai beau retourner le problème dans tous les sens, je ne vois pas comment régler le problème
    J'utilise la classe Loader pour charger 24 JPEG de 700 a 900Ko et le problème c'est la liberation de la mémoire .... je précise qu'a la fin du Loader je détruit tous les évènements (qui sont en weakReference) et avant de recommencer a charger de nouveau les mêmes images ,je fais un unload() et aussi un removeChild() sur tous les Loader placé sur la scene.

    voici le code de test du problème que j'ai mis dans un fichier a part :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    var tbImages:Array = [
    "http://lolo_test/aubadegrand/aubade_025.jpg",
    "http://lolo_test/aubadegrand/aubade_026.jpg",
    "http://lolo_test/aubadegrand/aubade_030.jpg",
    "http://lolo_test/aubadegrand/aubade_028.jpg",
    "http://lolo_test/aubadegrand/aubade_032.jpg",
    "http://lolo_test/aubadegrand/aubade_022.jpg",
    "http://lolo_test/aubadegrand/aubade_031.jpg",
    "http://lolo_test/aubadegrand/aubade_029.jpg",
    "http://lolo_test/aubadegrand/aubade_024.jpg",
    "http://lolo_test/aubadegrand/aubade_027.jpg",
    "http://lolo_test/aubadegrand/aubade_023.jpg",
    "http://lolo_test/aubadegrand/aubade_021.jpg",
    "http://lolo_test/aubadegrand/1192600283_mars2008.jpg",
    "http://lolo_test/aubadegrand/1192600434_juin2008.jpg",
    "http://lolo_test/aubadegrand/1192600478_juillet2008.jpg",
    "http://lolo_test/aubadegrand/1192600184_janvier2008.jpg",
    "http://lolo_test/aubadegrand/1192600330_avril2008.jpg",
    "http://lolo_test/aubadegrand/1192600527_aout2008.jpg",
    "http://lolo_test/aubadegrand/1192600676_novembre2008.jpg",
    "http://lolo_test/aubadegrand/1192600576_septembre2008.jpg",
    "http://lolo_test/aubadegrand/1192600621_octobre2008.jpg",
    "http://lolo_test/aubadegrand/1192600719_decembre2008.jpg",
    "http://lolo_test/aubadegrand/1192600113_couverture2008.jpg",
    "http://lolo_test/aubadegrand/1192600239_fevrier2008.jpg",
    "http://lolo_test/aubadegrand/1192600391_mai2008.jpg"
    ];
     
    // rajouter un ID derriere l'URL pour eviter le cache du navigateur
    var tbImg:Array = new Array();
    for(var a :Number = 0; a < tbImages.length; a++){
    	tbImg.push(tbImages[a] + "?x="+Math.round(Math.random()*1000000));
    }
     
    // Evenement fin de chargement du Loader
    function evtChargeReussi(ev:Event){
    	ev.target.removeEventListener(Event.COMPLETE, evtChargeReussi, false);
    	ev.target.removeEventListener(IOErrorEvent.IO_ERROR, evtChargeErreur, false);
    }
    function evtChargeErreur(ev:IOErrorEvent){
    	ev.target.removeEventListener(Event.COMPLETE, evtChargeReussi, false);
    	ev.target.removeEventListener(IOErrorEvent.IO_ERROR, evtChargeErreur, false);
    }
     
    // Lancement du chargement en masse
    btRelancer.addEventListener(MouseEvent.CLICK, relancer, false, 1, true);
    function relancer(ev:MouseEvent){
    	// effacement des Loader sur la scene
    	for (var a:uint = 0; a < this.numChildren; a++) {
    		var objet:* = this.getChildAt(a);
    		if(  objet is Loader ){
    			objet.unload();
    			this.removeChildAt(a);
    		}
    	}
    	var ecart:Number = 20;
    	var posEcart:Number = 20;
    	for (a = 0; a < this.tbImg.length; a++) {
    		var charg:Loader = new Loader();
    		charg.contentLoaderInfo.addEventListener(Event.COMPLETE, evtChargeReussi, false, 1, true);
    		charg.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, evtChargeErreur, false, 1, true);
    		charg.load(new URLRequest(this.tbImg[a]));
    		charg.x = posEcart;
    		charg.y = posEcart;
    		this.addChild(charg);
    		posEcart += ecart;
    	}
    }
     
    // affichage de l'utilisation mémoire
    this.addEventListener(Event.ENTER_FRAME, boucle);
    function boucle(ev:Event){
    	txMem.text = (Math.round(System.totalMemory/1024/1024*100)/100) +" Mo";
    }

    1-déja est ce que vous voyez une erreur dans le code qui empêcherait la libération de la mémoire ?

    2-sinon, comment vous faites pour régler ou contourner ce problème ?


    merci

  2. #2
    Membre habitué
    Homme Profil pro
    Creative Technologist
    Inscrit en
    Avril 2007
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Creative Technologist

    Informations forums :
    Inscription : Avril 2007
    Messages : 126
    Points : 174
    Points
    174
    Par défaut
    Ca c'est un problème pas simple. J'avais eu à le résoudre en Juillet 2008.
    Malheureusement, j'étais en mission en agence, et n'ai plus le code sous les yeux. Je vais donc parler de mémoire... sans certitude...

    Déjà, il me semble que le problème n'arrivait que sous le player 9 sous FireFox 2.0 sous Windows XP. Est-ce ta config? as-tu essayé sous IE? sur un autre système?
    J'en avais déduit à l'époque que c'était un bug du garbage collector du plugin.

    Pour contourner le problème, ne crées pas autant de Loader qu'il y a d'images. Crée un seul Loader, et quand il est "complete", fait un BitmapData.draw dans un BitmapData pour instancier ton image. Tu n'as alors pas besoin de purger le Loader. Tu relances directement le chargement avec le seul même et unique Loader.
    De cette manière, la seule fuite de mémoire que tu risques d'obtenir, est un doublon sur la dernière image chargée, ce qui n'est pas beaucoup, et donc acceptable.

    Notes que effectuer le draw dès que le Loader est "complete" pose parfois des problèmes, car l'image peut ne pas être encore disponible car pas encore décompilée. Il faut alors asynchroniser la méthode, et effectuer le draw quelques frames plus tard.
    La meilleure solution est certainement dans un "enterFrame", de tester le width de ton Loader. Tant que l'image n'est pas décompressée, le width est à 0. Dès que le width dépasse 0, draw, puis relance le loading pour l'image suivante.

    Bon courage

  3. #3
    Membre expérimenté Avatar de Lorenzo77
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    1 472
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2006
    Messages : 1 472
    Points : 1 537
    Points
    1 537
    Par défaut
    salut david, désolé pour cette réponse tardive --> fête + bouffe + boisson = cerveau pas réellement en fonction les jours suivant

    oui, je confirme que ce problème n'arrive qu'avec le plugin 9.0r124 / 9.0r151 avec FF et IE, le truc con c'est que ce plugin représente encore une trop grosse partie des utilisateurs ..
    pour le systeme je n'ai testé que XP.

    le coup du BitmapData.draw va etre trés chiant a mettre en place vu que ma classe "Chargeur" me permet de charger n'importe quoi sans s'occuper du type de fichier et aussi c'est un chargement en bloc dans mon cas (plus rapide de tous les lancer plutot qu'un par un)

    le test du code du 1er message :
    test Loader simple

    ce que je voulais faire :
    test1



    juste une info : il est préférable d'écouter l'évènement "init" plutôt que "complete" si tu as besoin d'accéder aux propriétés de l'objet chargé.


    donc que 2 soluces ... soit je zappes ceux ayant une vieille version du plugin (pas si vieille) ou alors je suis bon pour recréer une autre classe de chargement qui prendra en compte la version du plugin afin de le gérer différemment si ce sont des images ou autre chose

    zut, aucune des 2 me plait


    merci

  4. #4
    Membre habitué
    Homme Profil pro
    Creative Technologist
    Inscrit en
    Avril 2007
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Creative Technologist

    Informations forums :
    Inscription : Avril 2007
    Messages : 126
    Points : 174
    Points
    174
    Par défaut
    Mouais, c'est très chiant...

    Mais comme le problème vient d'un bug sur le garbage collector de la classe Loader, je ne vois pas comment tu peux faire autrement qu'en évitant au maximum d'utiliser un Loader (c'est à dire en fait n'en utiliser qu'un seul).

    Si tu refais une classe de chargement, peut-être est-il plus sage et pérenne de penser un chargement très bas niveau, en chargeant directement en binaire avec des BitesArray sur des URLStream. Ensuite, tu recomposes les objets dans le type dont tu as besoin. De mémoire, c'est comme ça que je fais d'habitude...
    (ça fait longtemps que j'ai pas ouvert le code de ma classe de chargement)...

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 69
    Points : 61
    Points
    61
    Par défaut
    Salut,

    Une petite réponse rapide qui j'espère n'est pas hors sujet.
    Le problème vient peut être de l'objet bitmpadata dans le loader qui ne se décharge pas?
    Pour le forcer à libérer sa mémoire:

    Bitmapdata.dispose()

    Je n'ai pas le temps de tester mais je le ferai prochainement car le sujet m'intéresse.

    a+

  6. #6
    Membre expérimenté Avatar de Lorenzo77
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    1 472
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2006
    Messages : 1 472
    Points : 1 537
    Points
    1 537
    Par défaut
    je confirme, les tests que j'ai fait montrent que le Bitmapdata.dispose() regle aussi le probleme ... quand meme fou d'être obligé d'utiliser ce genre de bidouille car les c......s d'abode ne sont pas capable de faire un debug propre de leur lecteur

Discussions similaires

  1. Rédiger un mémoire avec la classe Thloria ou Thesul
    Par thinhgt18 dans le forum Mise en forme
    Réponses: 1
    Dernier message: 03/10/2013, 12h01
  2. [Flash CS3][AS3]Charger clip avec une classe dynamique
    Par sourivore dans le forum ActionScript 3
    Réponses: 5
    Dernier message: 28/07/2007, 16h44
  3. Problème de mémoire avec BDE
    Par Machuet dans le forum Bases de données
    Réponses: 3
    Dernier message: 13/07/2004, 11h11
  4. Comment bien gerer la mémoire avec les TStringList?
    Par david_chardonnet dans le forum Langage
    Réponses: 5
    Dernier message: 18/06/2003, 10h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo