Memory profiling with Adobe Scout
 
- Requirements
 
Prerequisite knowledge
Avant de commencer ce didacticiel, consultez Prise en main d’Adobe Scout.
 
Required products
Adobe Scout CC
 
User level
Intermediate
 
Lorsque vous développez du contenu interactif, votre objectif principal est d’offrir des avantages inégalés à l’utilisateur. Les jeux, applications mobiles ou sites Web interactifs que vous développez doivent être rapides, dynamiques et accessibles. Pour atteindre cet objectif, l’exécution rapide de votre code n’est pas suffisante. Vous devez également tenir compte des exigences de votre contenu en matière de mémoire. Les périphériques mobiles disposent d’une mémoire limitée. Si vous ne faites pas attention, vous pouvez restreindre considérablement votre public. Mais ce n’est pas tout. L’allocation et la désallocation de mémoire sont des processus lents. Mieux vaut éviter des allocations de mémoire inutiles.
 
Adobe Scout est un outil essentiel de débogage des problèmes de mémoire dans le contenu Flash, qu’il soit exécuté dans un navigateur avec Flash Player ou fourni sous forme d’application mobile intégrant Adobe AIR. Cet article vous fera découvrir comment identifier les problèmes de mémoire et déterminer leur cause à l’aide de Scout. Vous allez découvrir en particulier la gestion de l’utilisation de la mémoire par Flash Player ainsi que les données de mémoire affichées dans Scout. Vous découvrirez également comment utiliser la nouvelle fonction de suivi d’allocation de mémoire de Scout 1.1, qui vous permet d’identifier rapidement des objets spécifiques résidant en mémoire ainsi que l’emplacement où ils sont alloués.
 
Sachez que cet article traite uniquement des fonctionnalités Scout en rapport avec le profiling de la mémoire. Si vous êtes novice dans Scout ou que vous vous intéressez au profiling des graphiques et performances, lisez d’abord le Guide de prise en main.
 
Modèle de mémoire Flash Player
 
Avant de commencer à déboguer les problèmes de mémoire à l’aide de Scout, il convient de comprendre comment Flash Player gère la mémoire. Flash Player peut allouer de la mémoire à partir de deux groupes de mémoire internes : la mémoire gérée et la mémoire non gérée.
 
La mémoire gérée est contrôlée par un « nettoyeur » de mémoire ; il n’est pas nécessaire de la désallouer explicitement. Tous les objets ActionScript sont stockés dans la mémoire gérée, tout comme certains objets utilisés en interne par Flash Player. En gros, Flash Player alloue un segment important de mémoire du système d’exploitation au stockage de nouveaux objets. Lorsque l’espace commence à manquer, Flash Player évite de demander davantage de mémoire au système d’exploitation et exécute un nettoyeur de mémoire pour récupérer une partie de sa mémoire existante. Le nettoyeur de mémoire recherche dans la mémoire gérée les objets obsolètes, puis réclame la mémoire qu’ils utilisent (on parle du processus de « marquage et balayage »). Un objet obsolète est un objet auquel on ne peut accéder à partir d’ActionScript dans la mesure où il est impossible de le référencer. Lorsque le nettoyeur de mémoire ne peut pas récupérer suffisamment de mémoire, il en demande davantage au système d’exploitation et étend le groupe de mémoire gérée.
 
La mémoire non gérée est sous le contrôle direct de Flash Player. Les objets doivent être désalloués explicitement lorsqu’ils ne sont plus utiles. Il n’est pas possible d’allouer de la mémoire non gérée directement d’ActionScript. Toutefois, certaines structures de données importantes, y compris des images, fichiers SWF et tableaux d’octets, sont stockées dans les « coulisses » de la mémoire non gérée. Lorsque vous créez un objet ActionScript qui fait référence à ces données (un objet d’affichage créé à partir d’une image, par exemple), il agit comme un « descripteur » (handle) pour la mémoire non gérée sous-jacente. La mémoire non gérée référencée par un objet ActionScript est désallouée lorsque l’objet est nettoyé (s’il est le seul objet à la référencer).
 
Figure 1. Modèle de mémoire Flash Player
Figure 1. Modèle de mémoire Flash Player
 
La figure 1 illustre l’interaction de Flash Player avec ces groupes de mémoire. Les objets gris sont techniquement obsolètes dans la mesure où il est impossible de les référencer. Toutefois, ils ne seront pas désalloués (avec le bitmap référencé) tant que le nettoyeur de mémoire ne sera pas à nouveau exécuté. Pour en savoir plus sur le fonctionnement du nettoyeur de mémoire, consultez l’article Mécanisme de nettoyage de la mémoire pour Flash Player et Adobe AIR.
 
Suivi de l’utilisation de la mémoire avec Scout
 
Avant de commencer une session dans Scout, vous pouvez sélectionner les données à recueillir sous Paramètres des nouvelles sessions. Indépendamment de votre sélection, chaque session enregistre des données de base sur ce qui se passe à l’intérieur de Flash Player, y compris des informations détaillées sur la quantité de mémoire utilisée par votre contenu. Ces données sont affichées dans la section Mémoire des panneaux Chronologie d’image et Résumé (voir Figure 2).
 
Figure 2. Résumé de l’utilisation de mémoire Flash Player dans Scout
Figure 2. Résumé de l’utilisation de mémoire Flash Player dans Scout
 
Le graphique du panneau Chronologie d’image illustre la quantité de mémoire que Flash Player utilisait à la fin de chaque image, répartie en catégories. Ce n’est qu’un instantané périodique de l’utilisation de mémoire. Il se révèle toutefois très utile pour détecter les fuites de mémoire entraînant une augmentation constante de l’utilisation de la mémoire au fil du temps que l’exécution du nettoyeur de mémoire ne peut pas réduire.
 
Le panneau Résumé indique l’utilisation de mémoire sur la plage d’images sélectionnée. Par défaut, il indique l’utilisation actuelle de la mémoire, une répartition de la mémoire en cours d’utilisation à la fin de la dernière image sélectionnée. Cliquez sur le bouton d’engrenage pour afficher l’utilisation moyenne ou maximale de la mémoire sur les images sélectionnées (voir Figure 3). Signification précise de ces paramètres :
 
  • La mémoire moyenne représente la moyenne pondérée dans chaque catégorie par rapport au temps. Elle ne correspond pas à la mémoire moyenne par image. Par exemple, lorsque vous sélectionnez deux images, chacune durant 80 ms et 20 ms et utilisant un total de 10 Mo et 90 Mo de mémoire respectivement, l’utilisation de mémoire totale est de 26 Mo ((10 Mo x 80 ms) + (90 Mo x 20 ms)) / (80 ms + 20 ms).
  • La mémoire maximale représente la valeur maximale pour chaque catégorie, sur la sélection. En d’autres termes, la somme des valeurs maximales de chaque catégorie peut dépasser la mémoire maximale utilisée. A titre d’illustration, imaginons le cas un peu exagéré de deux images utilisant 100 Mo de mémoire chacune, soit 90 Mo de bitmaps et 10 Mo d’objets ActionScript pour l’une, et 10 Mo de bitmaps et 90 Mo d’objets ActionScript pour l’autre. L’utilisation de mémoire maximale, tant Bitmap qu’Objets ActionScript, est de 90 Mo. Leur somme dépasse la mémoire utilisée maximale de 100 Mo.

 

Figure 3. Options d’affichage de la mémoire du panneau Résumé
Figure 3. Options d’affichage de la mémoire du panneau Résumé
 
Un examen plus approfondi des données du panneau Résumé permet de constater que Scout distingue la mémoire totale de la mémoire utilisée. Pour accélérer les allocations, Flash Player ne demande pas un supplément de mémoire au système d’exploitation chaque fois qu’il doit allouer un objet, mais obtient du système d’exploitation de grands blocs de mémoire dans lesquels il effectue les allocations internes. Il s’agit de mémoire aussi bien gérée que non gérée. La mémoire totale correspond à la somme de tous les blocs obtenus du système d’exploitation tandis que la mémoire utilisée correspond à la quantité de mémoire de ces blocs que Flash Player utilise.
 
En règle générale, la mémoire totale indiquée par Scout est légèrement inférieure à celle affichée dans le Moniteur d’activité d’OS X ou le Gestionnaires des tâches de Windows. En effet, certaines ressources sont directement allouées par le système d’exploitation plutôt que par Flash Player, telles que les descripteurs de fichiers et les ressources graphiques. Cette utilisation de mémoire supplémentaire est si minime qu’elle ne doit pas vous inquiéter.
 
Pour vous permettre d’identifier les problèmes de mémoire, le panneau Résumé répartit la mémoire utilisée en cinq catégories de niveau supérieur :
 
  • Objets ActionScript : mémoire gérée que Flash Player utilise. Cette mémoire correspond essentiellement aux allocations réalisées à partir d’ActionScript, mais elle inclut également la mémoire gérée que certains objets alloués en interne par Flash Player utilisent. Généralement, ces objets internes représentent environ 10 Mo de la mémoire dans cette catégorie, mais cette quantité est susceptible de varier en fonction du contenu.
  • Bitmaps : mémoire utilisée par les ressources graphiques telles que les images chargées, et mémoire utilisée par Flash Player lors du rendu, pour la mise en cache et l’application de filtres par exemple. Elles sont allouées à partir de la mémoire non gérée, mais fréquemment liées à des objets ActionScript, tels que des éléments de la liste d’affichage.
  • Tableaux d’octets : mémoire sous-jacente utilisée par les objets Tableau d’octets. Ils sont stockés dans la mémoire non gérée. Lorsque vous utilisez FlasCC, DomainMemory apparaît comme une sous-catégorie. Il s’agit du tableau d’octets utilisé en interne par FlasCC pour stocker vos objets C/C++.
  • Fichiers SWF : mémoire utilisée pour stocker les fichiers SWF que vous chargez, y compris le fichier SWF principal. Il s’agit de mémoire non gérée.
  • Autre : toute mémoire utilisée qui n’entre pas dans les catégories ci-dessus.
La catégorie Bitmap est répartie en plusieurs sous-catégories. Il se peut qu’elles ne soient pas toutes visibles lorsque vous exécutez votre contenu parce que Scout masque celles qui ne s’appliquent pas. Les sous-catégories de Bitmap sont les suivantes :
 
  • Images : mémoire utilisée pour stocker les images téléchargées à l’aide de l’instance Chargeur et généralement compressées. Il s’agit de fichiers JPG, GIF, PNG et ATF. Si vous incorporez une image dans un fichier SWF à l’aide de la balise de métadonnées [Embed], sa mémoire s’affiche sous Fichiers SWF plutôt que sous Images.
  • Objets d’affichage bitmap : mémoire que Flash Player utilise pour stocker la version décompressée des images chargées, que ce soit par le biais d’une instance Chargeur ou sous forme de ressource incorporée dans un fichier SWF. Elle inclut également la mémoire utilisée par les mipmaps.
  • BitmapData : mémoire utilisée pour stocker les objets BitmapData, y compris les objets qui sont des sous-classes de BitmapData. Ces données sont stockées dans la mémoire gérée et l’objet ActionScript BitmapData géré est simplement un descripteur de cette mémoire.
  • Tampons de filtre bitmap : mémoire utilisée pour stocker le résultat de l’application d’un filtre à un objet de liste d’affichage ou pour appliquer des effets tels que la mise à l’échelle.
  • Tampons CacheAsBitmap : mémoire utilisée pour mettre en cache le résultat du rendu d’un objet de liste d’affichage lorsque vous définissez les propriétés CacheAsBitmap et CacheAsBitmapMatrix .
  • Tampon d’écran principal : mémoire utilisée par Flash Player lors du rendu de la liste d’affichage. Ce tampon est copié dans l’écran à la fin de la passe de rendu. Il peut également être une cible pour d’autres sources, telles qu’une vidéo composite.
  • Autre mémoire bitmap : mémoire utilisée par d’autres opérations de rendu, telles que le rendu du texte. Malgré son nom, elle inclut également les sons téléchargés à l’aide d’une requête d’URL, car Flash Player utilise le même gestionnaire de mémoire pour les bitmaps et les sons.
La catégorie Autre contient la mémoire utilisée à des fins diverses, qui n’entrent pas précisément dans les autres catégories. Elle présente plusieurs sous-catégories :
  • Tampons réseau : mémoire utilisée par Flash Player pour stocker des paquets entrant sur le réseau avant leur traitement et des paquets en attente d’être envoyés.
  • Surcharge de Telemetry : mémoire utilisée par le profileur de Flash Player. Cette surcharge étant présente uniquement lorsque vous utilisez Scout, il est inutile de s’en inquiéter.
  • Autres lecteurs : mémoire utilisée par les instances de lecteur autres que celle que vous profilez si vous exécutez le module externe Flash Player dans un navigateur Web. La présence d’un autre contenu sur la même page ou l’exécution dans un autre onglet du navigateur peuvent en être la cause. La mémoire utilisée par d’autres opérateurs ActionScript entre également dans cette catégorie.
  • Sans catégorie : autre mémoire que Flash Player utilise mais dont il n’effectue pas encore le suivi. Il s’agit, par exemple, des tampons son et vidéo, des données XML, de la mémoire utilisée par Stage3D ainsi que de nombreuses petites structures de données que Flash Player utilise en interne. Il est prévu d’ajouter des catégories supplémentaires dans les prochaines versions de Scout.
Notez que la catégorie ActionScript est la seule qui utilise la mémoire gérée. Si votre contenu alloue continuellement puis abandonne un grand nombre d’objets, cette catégorie a tendance à évoluer en dents de scie (voir Figure 4). A mesure que Flash Player alloue de nouveaux objets ActionScript, l’utilisation de la mémoire augmente progressivement. Au bout d’un moment, l’espace pour l’allocation d’objets supplémentaires est saturé et un nettoyage de mémoire est déclenché. A ce stade, Flash Player récupère la mémoire des objets qui ne sont plus référencés et l’utilisation de mémoire chute brusquement. Notez que la mémoire totale ne diminue pas ; Flash Player conserve la mémoire obtenue du système d’exploitation, qu’il remplira certainement à nouveau.
 
Figure 4. Evolution en dents de scie de l’utilisation de la mémoire gérée
Figure 4. Evolution en dents de scie de l’utilisation de la mémoire gérée
 
Ce comportement pose un problème : le nettoyage de mémoire se révèle onéreux en termes de calcul et le contenu risque de s’afficher par à-coups. Si la rotation est élevée pour un certain type d’objet, il peut se révéler judicieux de regrouper les objets de sorte à réutiliser les mêmes objets sans avoir à en allouer des nouveaux. Bien entendu, vous devez d’abord identifier les objets qui sont à l’origine du problème. Heureusement, Scout 1.1 inclut la nouvelle fonction de suivi des allocations de mémoire.
 
Suivi des allocations de mémoire avec Scout
 
Pour obtenir la répartition détaillée des objets en mémoire, activez le suivi des allocations de mémoire sous Paramètres des nouvelles sessions (voir Figure 5). Flash Player enregistre alors les allocations et désallocations de mémoire, puis envoie ces informations à Scout. Flash Player suit chaque allocation effectuée par votre code ActionScript et les allocations importantes qu’il effectue de votre part (en particulier, les éléments qui entrent dans les catégories Bitmap, Tableaux d’octets et Fichiers SWF). Il n’enregistre pas toutes les allocations effectuées par Flash Player, mais seules celles qui constituent une conséquence directe de l’exécution de votre contenu.
 
Figure 5. Suivi des allocations de mémoire sous Paramètres des nouvelles sessions
Figure 5. Suivi des allocations de mémoire sous Paramètres des nouvelles sessions
 
Le paramètre Suivi des allocations de mémoire nécessite une version de débogage de Flash Player lorsque vous exécutez votre contenu dans un navigateur Web. Le contenu AIR ne requiert aucune action spéciale de votre part ; vous pouvez utiliser ce paramètre pour profiler votre contenu validé. Gardez également à l’esprit que vous devez activer la fonction Telemetry avancé pour que votre contenu puisse l’utiliser. Pour plus d’informations sur l’activation de cette fonction, consultez le Guide de prise en main.
 
Figure 6. Panneau Allocations de mémoire dans Scout
Figure 6. Panneau Allocations de mémoire dans Scout
 
Vous pouvez consulter les données recueillies par Flash Player dans le panneau Allocations de mémoire de Scout. La vue par défaut de ce panneau indique les traces de pile ActionScript où des objets ont été alloués dans les images que vous avez sélectionnées (voir Figure 6). Développez les traces de pile pour afficher le nombre d’objets alloués de chaque classe. Les allocations produites en dehors d’ActionScript en raison d’activités Flash Player internes sont également affichées. Par exemple, la Figure 6 indique que la préparation du bytecode ActionScript a entraîné 20 allocations.
 
Par défaut, le panneau Allocations de mémoire affiche uniquement les allocations d’objets qui étaient encore actives à la fin de la dernière image sélectionnée. Autrement dit, il n’affiche pas les objets alloués mais nettoyés dans les images que vous avez sélectionnées. Pour afficher tous les objets, y compris ceux qui ont été nettoyés, désactivez le filtre Masquer les objets nettoyés (voir Figure 7).
 
Figure 7. Désactivation du filtre Masquer les objets nettoyés
Figure 7. Désactivation du filtre Masquer les objets nettoyés
 
Il est important de noter que le panneau Allocations de mémoire indique uniquement les objets alloués dans les images que vous avez sélectionnées. Il n’inclut pas les objets alloués sur une image antérieure même s’ils sont toujours actifs dans les images sélectionnées. Pour afficher tous les objets en cours dans l’image n, vous devez sélectionner les images 1 à n dans Scout.
 
Bien que la vue du haut vers le bas soit utile pour comprendre où les allocations se produisent par rapport à l’exécution de votre code, seul le nombre total d’allocations pour chaque type d’objet vous intéresse vraiment. La vue Objets du bas vers le haut affiche le nombre d’allocations de chaque classe (Figure 8). Développez un objet pour connaître ce qui a entraîné l’allocation.
 
Figure 8. Vue Objets du bas vers le haut
Figure 8. Vue Objets du bas vers le haut
 
Vous vous demandez peut-être pourquoi la coloration des objets est différente de celle des appels de fonction. La couleur des objets est fonction de la catégorie de mémoire à laquelle ils appartiennent dans le panneau Résumé. Bien que la plupart des allocations soient des objets ActionScript, Scout indique également d’autres allocations importantes. Par exemple, les allocations nécessitant la plus grande quantité de mémoire à la Figure 9 correspondent aux objets d’affichage bitmap. Il est possible de voir que ces allocations ont été créées en interne par Flash Player lors du téléchargement d’une texture et de la décompression d’images.
 
Figure 9. Codage de couleur d’objet en fonction des catégories de mémoire
Figure 9. Codage de couleur d’objet en fonction des catégories de mémoire
 
Outre les classes les plus allouées, il est utile de savoir quelles fonctions effectuent le plus d’allocations. Vous pouvez ainsi optimiser des fonctions spécifiques. Par exemple, vous pouvez réutiliser des objets plutôt que d’en allouer chaque fois des nouveaux. La vue Fonctions du bas vers le haut répertorie les fonctions selon le nombre d’allocations qu’elles effectuent directement, par opposition à indirectement par appel d’une autre fonction (voir Figure 10).
 
Figure 10. Vue Fonctions du bas vers le haut
Figure 10. Vue Fonctions du bas vers le haut
 
Vous pouvez développer une fonction afin d’afficher une répartition des objets alloués pour tous ses appels et les autres fonctions responsables de son appel.
 
Jusqu’à présent, vous avez vu comment utiliser le panneau Allocations de mémoire pour examiner les allocations. Or, il vous permet également de connaître le moment de la désallocation des objets. Si vous remplacez le paramètre Allocations par Désallocations, les objets désalloués pendant les images sélectionnées s’affichent. Vous pouvez également filtrer le panneau Allocations de mémoire à partir des panneaux Séquence d’activité ou Activités principales (voir Figure 11). Cela revient à filtrer le panneau ActionScript. Vous pouvez voir les objets qui ont été désalloués au cours d’un nettoyage de mémoire spécifique.
 
Figure 11. Mode Désallocation du panneau Allocations de mémoire
Figure 11. Mode Désallocation du panneau Allocations de mémoire
 
Lorsque vous profilez une session en direct, vous pouvez obliger Flash Player à arrêter ses activités et effectuer le nettoyage complet de la mémoire en cliquant sur le bouton situé dans le coin supérieur gauche du panneau Allocations de mémoire (voir Figure 12). Cela peut s’avérer très utile pour vous assurer que vous regardez les objets vraiment actifs dans Scout et que ceux-ci n’attendent pas d’être nettoyés tout simplement.
 
Figure 12. Forçage du nettoyage de la mémoire
Figure 12. Forçage du nettoyage de la mémoire
 
Problèmes connus de profiling de la mémoire
 
Lorsque vous utilisez Scout dans le cadre du profiling de la mémoire, tenez compte des points suivants :
 
  • Les tableaux initialisés statiquement dans du contenu compilé AOT pour iOS ne s’affichent pas dans le panneau Allocations de mémoire. Ce problème sera résolu dans la prochaine version d’AIR, mais vous pouvez le résoudre en attendant en initialisant les tableaux dans un constructeur.
  • Les objets qui sont des sous-classes de BitmapData ne s’affichent pas dans la couleur de la catégorie BitmapData dans le panneau Allocations de mémoire. Scout leur attribue la couleurs des objets ActionScript parce qu’il ignore votre hiérarchie de classe. Dans le panneau Résumé, leur utilisation de mémoire est incluse dans la catégorie BitmapData.
  • Il arrive parfois que le fichier SWF initial et le tampon d’écran principal ne s’affichent pas dans le panneau Allocations de mémoire. Ils sont cependant toujours inclus dans les données du panneau Résumé.
  • Lorsque vous additionnez la mémoire utilisée par les objets ActionScript dans le panneau Allocations de mémoire, le résultat est inférieur au total indiqué dans le panneau Résumé. En effet, la catégorie Objets ActionScript inclut de la mémoire allouée en interne par Flash Player, qui utilise également la mémoire gérée. Rien d’inquiétant.
  • La mémoire utilisée en interne par Stage3D n’est pas explicitement identifiée dans le panneau Résumé. Les textures et autres ressources que vous chargez s’affichent (par exemple sous Images ou Tableaux d’octets), mais la mémoire utilisée par OpenGL ou DirectX en coulisse entre dans la catégorie Sans catégorie.
  • La mémoire utilisée par les tampons pour la lecture de vidéo et de son n’est pas explicitement identifiée dans le panneau Résumé. Cette mémoire est incluse dans la catégorie Sans catégorie.

 

Pour aller plus loin
 
Les connaissances dont vous disposez maintenant sur le modèle de mémoire de Flash Player et les fonctions de profiling de mémoire de Scout vous permettront d’identifier et suivre plus efficacement les problèmes de votre contenu liés à la mémoire. Pour en savoir plus sur le fonctionnement de Flash Player, consultez les articles Mécanisme de nettoyage de la mémoire pour Flash Player et Adobe AIR et Comprendre Flash Player avec Adobe Scout.