2010-06-01 4 views
1

Je rencontre des problèmes avec la gestion de la mémoire dans une application flash. L'utilisation de la mémoire se développe un peu, et j'ai suivi la façon dont je charge les actifs.Utilisation de la mémoire dans Flash/Flex/AS3

-je intégrer plusieurs images raster dans une classe intégrée, comme celui-ci

[Embed(source="/home/gabriel/text_hard.jpg")] 
public static var ASSET_text_hard_DOT_jpg : Class; 

Je puis par exemple les actifs de cette façon

var pClass : Class = Embedded[sResource] as Class; 
return new pClass() as Bitmap; 

À ce stade, l'utilisation de la mémoire monte, ce qui est tout à fait normal . Cependant, null toutes les références à l'objet ne libère pas la mémoire. Sur la base de ce comportement, il semble que le lecteur Flash crée une instance de la classe la première fois que je la demande, mais ne la libère jamais - pas sans références, en appelant System.gc(), en faisant le double tour LocalConnection ou en appelant dispose() sur les objets BitmapData.

Bien sûr, ceci est très indésirable - l'utilisation de la mémoire augmenterait jusqu'à ce que tout ce qui est dans les fichiers SWF soit instancié, que j'aie cessé d'utiliser un actif il y a longtemps.

Mon analyse est-elle correcte? Peut-on faire quelque chose pour résoudre ce problème?

Répondre

0

Il s'avère que je gardais des références aux objets qui n'ont pas été déchargés. Très délicats. Le GC fonctionne correctement dans tous les cas que j'ai décrits, ce que je soupçonne peut-être différent. Plus précisément, charger un fichier SWF, y ajouter des classes, les ajouter à la liste d'affichage, les manipuler, puis supprimer toutes les références et décharger le fichier SWF me laisse presque exactement la même mémoire que celle que j'ai commencée.

0

Pourquoi voulez-vous utiliser ceci ??? Parfois, l'affectation dynamique des ressources est boguée et ne peut être libérée. J'ai eu des problèmes similaires auparavant avec flash player et flex, par ex. charger et décharger le même swf externe ... la mémoire augmentait constamment avec la taille du swf chargé sans descendre même si j'appelais le system.gc(); après avoir déchargé le swf. Donc, ma suggestion est d'ignorer cette approche et d'utiliser le premier cas que vous avez décrit.


MISE À JOUR 1

<?xml version="1.0" encoding="utf-8"?> 
<s:Application 
    xmlns:fx   = "http://ns.adobe.com/mxml/2009" 
    xmlns:s   = "library://ns.adobe.com/flex/spark" 
    xmlns:mx   = "library://ns.adobe.com/flex/mx" 
    creationComplete = "creationComplete()"> 

<fx:Script> 
    <![CDATA[ 



     [Embed(source="/assets/logo1w.png")] 
     private static var asset1:Class; 

     [Embed(source="/assets/060110sinkhole.jpg")] 
     private static var asset2:Class; 


     private static var _dict:Dictionary = new Dictionary(); 

     private static function initDictionary():void 
     { 
      _dict["/assets/logo1w.png"] = asset1; 
      _dict["/assets/060110sinkhole.jpg"] = asset2; 
     } 

     public static function getAssetClass(assetPath:String):Class 
     { 
      // if the asset is already in the dictionary then just return it 
      if(_dict[assetPath] != null) 
      { 
       return _dict[assetPath] as Class; 
      } 

      return null; 
     } 

     private function creationComplete():void 
     { 
      initDictionary(); 
      var asset1:Class = getAssetClass("/assets/logo1w.png"); 
      var asset2:Class = getAssetClass("/assets/060110sinkhole.jpg"); 
      var asset3:Class = getAssetClass("/assets/logo1w.png"); 
      var asset4:Class = getAssetClass("/assets/060110sinkhole.jpg"); 
      var asset5:Class = getAssetClass("/assets/logo1w.png"); 
     } 
    ]]> 
</fx:Script> 

+1

Désolé, je ne suis pas tout à fait. Je n'ai décrit qu'une seule façon de le faire. Le premier extrait montre comment j'intègre les actifs et le second comment je les utilise. Voulez-vous dire pourquoi je ne fais pas juste 'new ASSET_text_hard_DOT_jpg()'? C'est parce que mon code est assez complexe et ne sait pas toujours à l'avance qu'il a besoin, par exemple il crée une chaîne de plusieurs morceaux et obtient cette image nommée (ie "text_" + s_lDifficulty [nDifficulty] -> "text_hard") – ggambett

+0

I Je suis désolé mais je pense que la chose que vous essayez de réaliser n'est pas possible. D'après ce que je sais, les ressources sont intégrées lors de la construction du swf, je ne suis pas sûr que vous puissiez incorporer une ressource dynamiquement comme vous l'avez décrit. Ce que je ferais pour créer un dictionnaire et y mettre toutes les ressources dont j'ai besoin. Je l'utiliserais comme dans le code UPDATE1 que j'ai écrit maintenant dans la réponse. –

1

Assurez-vous d'exécuter à nouveau vos tests dans le lecteur non-debug. Le lecteur de débogage ne récupère pas toujours toute la mémoire correctement lors de la libération des ressources. En outre, étant donné que vous utilisez un élément incorporé plutôt qu'un élément chargé, les données réelles ne seront peut-être jamais divulguées. Comme il fait partie de votre SWF, je dirais que vous pourriez raisonnablement s'attendre à ce qu'il soit en mémoire pour la durée de vie de votre SWF.

0

À ce stade, l'utilisation de la mémoire augmente, ce qui est parfaitement normal. Cependant, annulant toutes les références à l'objet ne libère pas la mémoire.

C'est aussi parfaitement normal. Il est rare qu'un système garantisse que le moment où vous arrêtez de référencer un objet dans le code est le même moment où la mémoire correspondant est renvoyée au système d'exploitation. C'est exactement pourquoi des méthodes comme System.gc() sont là, pour vous permettre de forcer un nettoyage quand vous en avez besoin. Habituellement, l'application peut implémenter une sorte de mise en commun pour conserver les objets et la mémoire à des fins d'efficacité (car l'allocation de mémoire est généralement lente).Et même si l'application renvoie la mémoire au système d'exploitation, le système d'exploitation peut quand même la considérer comme affectée à l'application pendant un certain temps, au cas où l'application en demanderait un peu plus tard.

Vous ne devez vous inquiéter que si cette mémoire libérée n'est pas réutilisée. Par exemple, vous devriez constater que si vous créez un objet, le libérez et répétez ce processus, l'utilisation de la mémoire ne devrait pas croître linéairement avec le nombre d'objets que vous créez, car la mémoire des objets précédemment libérés est réaffectée aux nouveaux. Si vous pouvez confirmer que cela ne se produit pas, éditez votre question pour le dire. :)