
Profilage et perfectionnement des performances de votre jeu pour une large gamme de plateformes et d'appareils, vous pouvez élargir votre base de joueurs et augmenter vos chances de succès.
Cette page fournit des informations sur deux outils d'analyse de l'utilisation de la mémoire dans votre application dans Unity: le module Profileur de mémoire intégré, et le package Profileur de mémoire, un pack Unity que vous pouvez ajouter à votre projet.
Les informations ici sont extraites de l'ebook, Ultimate guide to profileing Unity games, disponible gratuitement en téléchargement. L'ebook a été créé par des experts Unity externes et internes en développement, profilage et optimisation de jeux.
Lisez la suite pour en savoir plus sur le profilage de la mémoire dans Unity.
Le profilage de mémoire est utile pour effectuer des tests sur les limitations de mémoire de la plateforme matérielle, réduire le temps de chargement et les pannes et rendre votre projet compatible avec les appareils plus anciens. Cela peut également être pertinent si vous souhaitez améliorer les performances du processeur ou du GPU en effectuant des modifications qui augmentent réellement l'utilisation de la mémoire. Il n'est en grande partie pas lié aux performances d'exécution.
Dans Unity, il existe deux façons d'analyser l'utilisation de la mémoire dans votre application.
Le module Profiler de mémoire : Il s'agit d'un module de profiler intégré qui vous donne des informations de base sur l'endroit où votre application utilise la mémoire.
Le package Profileur de mémoire : Il s'agit d'un package Unity que vous pouvez ajouter à votre projet. Il ajoute une fenêtre supplémentaire Profileur de mémoire à l'éditeur Unity, que vous pouvez ensuite utiliser pour analyser encore plus en détail l'utilisation de la mémoire dans votre application. Vous pouvez stocker et comparer des captures d'écran, afin de localiser les fuites de mémoire ou de visualiser sa configuration pour déterminer d'éventuels problèmes de fragmentation.
Grâce à ces outils intégrés, vous pouvez surveiller l'utilisation de la mémoire, localiser les zones d'une application où l'utilisation de la mémoire est plus élevée que prévu, et trouver et améliorer la fragmentation de la mémoire.

La compréhension et la budgétisation des limitations de mémoire de vos appareils cibles sont essentielles pour le développement multiplateforme. Quand vous concevez des scènes et des niveaux, respectez le budget mémoire défini pour chaque appareil cible. En fixant des limites et des lignes directrices, vous pouvez vous assurer que votre application fonctionne bien dans les limites des spécifications matérielles de chaque plateforme.
Vous trouverez les spécifications de la mémoire de l'appareil dans la documentation du développeur. Par exemple, selon la documentation, la console Xbox One est limitée à 5 Go de mémoire maximale disponible pour les jeux exécutés au premier plan.
Il peut également être utile de définir des budgets de contenu autour de la complexité des maillages et des shaders, ainsi que pour la compression des textures. Tout ceci joue sur la quantité de mémoire allouée. Ces chiffres budgétaires peuvent être consultés au cours du cycle de développement du projet.
Déterminer les limites physiques de la mémoire vive
Chaque plateforme cible a une limite de mémoire et, une fois que vous la connaissez, vous pouvez définir un budget mémoire pour votre application. Utilisez le Profileur de mémoire pour regarder une capture instantanée. Les ressources matérielles (voir l'image ci-dessus) montrent la taille de la mémoire vive physique (RAM) et de la mémoire vive vidéo (VRAM). Ce chiffre ne tient pas compte du fait que tout cet espace pourrait ne pas être disponible. Cependant, il fournit une figure de balle utile pour commencer à travailler.
C'est une bonne idée de croiser les spécifications matérielles de référence pour les plateformes cibles, car les chiffres affichés ici peuvent ne pas toujours donner une image complète. Le matériel du kit développeur a parfois plus de mémoire ou vous travaillez peut-être avec du matériel ayant une architecture de mémoire unifiée.
Identifiez le matériel avec les spécifications les plus basses en termes de mémoire vive pour chaque plateforme prise en charge et utilisez-les pour guider votre décision de budget mémoire. Souvenez-vous que toute cette mémoire physique n'est peut-être pas disponible. Par exemple, une console peut être dotée d'un hyperviseur pour prendre en charge les jeux plus anciens qui pourraient utiliser une partie de la mémoire totale. Pensez à un pourcentage (par exemple, 80 % du total) à utiliser. Pour les plateformes mobiles, vous pouvez également envisager de scinder en plusieurs niveaux de spécifications afin de soutenir une meilleure qualité et des fonctionnalités pour ceux qui ont des appareils plus haut de gamme.
Une fois votre budget mémoire défini, envisagez de le définir par équipe. Par exemple, les artistes de votre environnement utilisent une certaine quantité de mémoire pour chaque niveau ou scène chargé, l'équipe audio reçoit une allocation de mémoire pour la musique et les effets sonores, etc.
Il est important d'être flexible avec les budgets au fur et à mesure de l'avancement du projet. Si une équipe n'atteint pas le budget, assignez le surplus à une autre équipe si cela peut améliorer les parties du jeu qu'elle développe.
Une fois que vous avez décidé et défini les budgets mémoire pour vos plateformes cibles, l'étape suivante consiste à utiliser des outils de profilage pour vous aider à surveiller et à suivre l'utilisation de la mémoire dans votre jeu.

Le module Profileur de mémoire fournit deux vues : Simpleet détaillé. Utilisez la fenêtre Simple pour obtenir une vue de haut niveau de l'utilisation de la mémoire pour votre application. Si nécessaire, passez à la vue détaillée pour creuser davantage.
Simple
Le chiffre Total de la mémoire réservée est le « Total suivi par la mémoire Unity ». Il inclut la mémoire que Unity a réservée, mais n'utilise pas actuellement (ce chiffre correspond au total de mémoire utilisée).
La figure System Used Memory est ce que l'OS considère comme étant utilisé par votre application. Si jamais cette figure affiche 0, sachez que cela indique que le compteur Profiler n'est pas implémenté sur la plateforme que vous profilez. Dans ce cas, le meilleur indicateur à prendre en compte est la mémoire totale réservée. Il est également recommandé de passer à un outil natif de profilage de plateforme pour obtenir des informations détaillées sur la mémoire dans ces cas.

Pour étudier la quantité de mémoire utilisée par votre fichier exécutable, les DLL et la Mono Virtual Machine, les chiffres de mémoire image par image ne permettront pas de la couper. Utilisez une capture d'instantané détaillée pour analyser ce genre de panne de mémoire.
Note : L'arborescence de référence dans l'aperçu détaillé du module Profileur de mémoire n'affiche que des références natives. Les références d'objets de types héritant de UnityEngine.Object peuvent apparaître avec le nom de leurs shells gérés. Cependant, ils peuvent apparaître uniquement parce qu'ils ont des objets natifs en dessous. Vous ne verrez pas nécessairement de type géré. Prenons comme exemple un objet dont l'un des champs est Texture2Din comme référence. En utilisant cette vue, vous ne verrez pas non plus quel champ contient cette référence. Pour ce genre de détail, utilisez le package Profileur de mémoire.
Pour déterminer à un haut niveau quand l'utilisation de la mémoire commence à approcher les budgets de la plateforme, utilisez le calcul suivant « à l'arrière de la serviette » :
Système utilisé Mémoire (ou mémoire totale réservée si le système utilisé affiche 0) + mémoire tampon ballpark de mémoire non suivie / mémoire totale de la plateforme
Lorsque ce chiffre approche 100 % du budget mémoire de votre plateforme, utilisez le package Profileur de mémoire pour comprendre pourquoi.
De nombreuses fonctionnalités du module Profileur de mémoire ont été remplacées par le package Profileur de mémoire, mais vous pouvez toujours l'utiliser pour compléter vos efforts d'analyse de mémoire.
Par exemple :
Pensez à profiler l'appareil qui a les spécifications les plus basses pour votre plateforme cible globale lorsque vous définissez un budget mémoire. Surveillez de près l'utilisation de la mémoire en gardant à l'esprit vos limites cibles.
Vous voudrez généralement profiler à l'aide d'un puissant système de développement avec beaucoup de mémoire disponible (l'espace pour stocker de grandes captures de mémoire ou les charger et les enregistrer rapidement est important).
Le profilage de mémoire est une bêterie par rapport au profilage du processeur et du GPU, car il peut entraîner une surcharge supplémentaire de mémoire. Vous devrez peut-être profiler la mémoire sur des appareils haut de gamme (avec plus de mémoire), mais attention en particulier à la limite du budget mémoire pour la spécification cible bas de gamme.
Points à prendre en compte lors du profilage pour l'utilisation de la mémoire :
Note : L'éditeur Unity affichera généralement toujours une empreinte mémoire plus grande en raison d'objets supplémentaires chargés à partir de l'éditeur et du profiler. Il peut même afficher de la mémoire de ressources qui ne serait pas chargée en mémoire dans une compilation, comme à partir de groupes de ressources (selon le mode de simulation Addressables) ou de sprites et atlas, ou pour les ressources affichées dans l'Inspector. Certaines chaînes de référence peuvent également être plus confuses dans l'éditeur.

Le Profileur de mémoire est actuellement disponible en aperçu pour le LTS pour Unity 2019 ou version ultérieure, mais devrait être vérifié dans le LTS pour Unity 2022.
L'un des principaux avantages du package du Profileur de mémoire est qu'il vous permet non seulement de capturer des objets natifs (comme le fait le module Profileur de mémoire), mais aussi de visualiser la mémoire gérée, d'enregistrer et de comparer des instantanés et d'explorer le contenu de la mémoire encore plus en détail, avec des répartitions visuelles de votre utilisation de la mémoire.
Un aperçu montre les allocations de mémoire dans le moteur, ce qui vous permet d'identifier rapidement les causes d'une utilisation excessive ou inutile de la mémoire, de traquer les fuites de mémoire ou de voir la fragmentation du tas.
Après avoir installé le package Profiler de mémoire, ouvrez-le en cliquant sur Window > Analysis > Memory Profiler.
La barre de menus supérieure du Profileur de mémoire vous permet de modifier la cible de sélection des joueurs et de capturer ou d'importer des instantanés.
Note : Profilez la mémoire sur l'équipement cible en connectant le profileur de mémoire à l'appareil distant grâce à la liste déroulante de sélection Target. Le profilage dans l'éditeur Unity vous donnera des chiffres inexacts en raison des frais généraux ajoutés par l'éditeur et d'autres outils.

Sur la gauche de la fenêtre du profileur de mémoire se trouve Workbencharea. Utilisez ceci pour gérer et ouvrir ou fermer des instantanés de mémoire enregistrés. Vous pouvez également utiliser cette zone pour basculer entre les vues Single et Compare Snapshots.
Comme Profile Analyzer, le profileur de mémoire vous permet de charger deux ensembles de données (instantanés de mémoire) pour les comparer. Ceci est particulièrement utile pour observer comment l'utilisation de la mémoire a augmenté au fil du temps ou entre les scènes et pour rechercher des fuites de mémoire.
Le Profileur de mémoire dispose d'un certain nombre d'onglets dans la fenêtre principale qui vous permettent d'explorer des captures de mémoire, y compris Résumé, Objets et allocations et Fragmentation. Examinons chacune de ces options en détail.

Choisissez cette vue lorsque vous souhaitez obtenir un aperçu rapide de l'utilisation de la mémoire d'un projet. Il contient également des chiffres utiles et importants relatifs à la mémoire pour l'instantané de mémoire capturé en question. Il est parfait pour un coup d'œil rapide sur ce qui se passe au moment où une capture a été prise.

La vue Tree Map affiche une répartition de la mémoire utilisée par les objets comme Arbre Map graphique que vous pouvez explorer pour découvrir le type d'objets qui consomment le plus de mémoire.

Sous la fenêtre Tree Map se trouve un tableau filtré qui se met à jour pour afficher la liste des objets dans les cellules de la grille sélectionnées.
La Tree Map montre la mémoire attribuée aux objets, qu'ils soient natifs ou gérés. La mémoire des objets gérés a tendance à être éclipsée par la mémoire des objets natifs, ce qui la rend plus difficile à repérer dans la vue de la carte. Vous pouvez zoomer sur la Tree Map pour les regarder, mais pour l'inspection d'objets plus petits, les tableaux fournissent généralement une meilleure vue d'ensemble. Le fait de cliquer sur les cellules de la Tree Map filtrera le tableau situé en dessous selon le type de section et/ou sélectionnera l'objet spécifique qui vous intéresse dans le tableau.
Vous pouvez rechercher quels objets de référence de cette liste et éventuellement dans quels champs de classe gérés ces références résident en sélectionnant la ligne de tableau ou la cellule de grille Tree Map qui la représente, puis en cochant la section Références dans le panneau latéral Détails. Si le côté est caché, vous pouvez le rendre visible via un bouton à bascule dans la partie supérieure droite de la barre d'outils.
Note : La Tree Map n'affiche que les objetsen mémoire. Ce n'est pas une représentation complète de la mémoire suivie. Ceci est important de comprendre au cas où vous remarqueriez que les chiffres de la présentation de l'utilisation de la mémoire ne sont pas les mêmes que le total de la mémoire suivie.
Ceci résulte du fait que toute la mémoire native n'est pas liée aux objets. Il peut également consister en des allocations natives non associées à des objets telles que des fichiers exécutables et des DLL, des NativeArrays, etc. Des concepts encore plus abstraits tels que « Espace mémoire réservé mais non utilisé » peuvent jouer dans le total des allocations natives.

La vue Objets et allocations montre un tableau qui peut être basculé vers un filtre en fonction de sélections prêtes à l'emploi, telles que Tous les objets, Tous les objets natifs, Tous les objets gérés, Toutes les allocations natives, etc.
Vous pouvez changer le tableau du bas pour afficher les objets, allocations ou régions de mémoire dans la plage sélectionnée. Comme indiqué dans l'aperçu Tree Map, toute la mémoire n'est pas associée à des objets, de sorte que les pages All Memory Regions et All Native Allocations peuvent fournir une image plus complète de votre utilisation de la mémoire, où les régions de mémoire incluent également la mémoire réservée mais actuellement inutilisée.
Utilisez ceci à votre avantage lorsque vous optimisez l'utilisation de la mémoire et visez à emballer la mémoire plus efficacement pour les plateformes matérielles où les budgets mémoire sont limités.
Chargez une capture du Profileur de mémoire et passez par l'aperçu Tree Map pour inspecter les catégories, ordonnées du plus grand au plus petit en taille d'empreinte mémoire.
Les ressources de projet sont souvent les plus gros consommateurs de mémoire. À l'aide de l'affichage Tableau, localisez les objets de texture, les maillages, les audioclips, les RenderTextures, les shaders et les tampons préalloués. Ce sont tous de bons candidats pour l'optimisation de la mémoire.
Une fuite de mémoire se produit généralement lorsque :
Le mode de comparaison du profileur de mémoire peut aider à trouver les fuites de mémoire en comparant deux captures sur une période donnée.
Un scénario courant de fuite de mémoire dans les jeux Unity peut se produire après le déchargement d'une scène.
Le package du Profileur de mémoire dispose d'un flux de production qui vous guide tout au long du processus de découverte de ces types de fuites à l'aide du mode Compare.
Grâce à la comparaison différentielle de plusieurs captures de mémoire, vous pouvez identifier la source d'allocations de mémoire continues pendant le cycle de vie de l'application.
Les sections suivantes répertorient quelques conseils pour vous aider à identifier les allocations de piles gérées dans vos projets.

Le module Profileur de mémoire du Profileur Unity représente les allocations gérées par image avec une ligne rouge. Cette valeur doit être 0 la plupart du temps, donc tous les pics dans cette ligne indiquent les frames que vous devez rechercher pour les allocations gérées.

La vue Timeline du module du profileur d'utilisation du processeur montre les allocations, y compris celles gérées, en rose, ce qui les rend faciles à voir et à affiner.

Les piles d'appel d'allocation permettent de découvrir rapidement les allocations de mémoire gérées dans votre code. Ceux-ci fourniront les détails de la pile d'appels dont vous avez besoin à moindre surcharge par rapport à ce que le profilage profond ajouterait normalement, et ils peuvent être activés à la volée à l'aide du Profiler standard.
Les piles d'appel d'allocation sont désactivées par défaut dans le Profiler. Pour les activer, cliquez sur le bouton Call Stacks dans la barre d'outils principale de la fenêtre Profiler. Changez l'affichage Détails en Données connexes.
Note : Si vous utilisez une version plus ancienne de Unity (avant la prise en charge de la pile d'exécution des allocations), le profilage approfondi est un bon moyen d'obtenir des piles d'exécution complètes pour trouver les allocations gérées.
Les exemples GC sélectionnés dans Hierarchy ou Raw Hierarchy contiendront désormais leurs piles d'appels. Vous pouvez également voir les piles d'appel des exemples GC dans l'infobulle de sélection dans Timeline.

L'aperçu hiérarchique dans le profileur d'utilisation du processeur vous permet de cliquer sur les en-têtes de colonne pour les utiliser comme critères de tri. Le tri par GC Alloc est un excellent moyen de se concentrer sur ces éléments.
Project Auditor est un outil expérimental d'analyse statique. Il fait beaucoup de choses utiles, dont plusieurs n'entrent pas dans le cadre de ce guide, mais il peut produire une liste de chaque ligne de code dans un projet qui provoque une allocation gérée, sans même avoir à exécuter le projet. C'est un moyen très efficace de trouver et d'examiner ce genre de problèmes.
Unity utilise le Garbage collector Boehm-Demers-Weiser, qui cesse d'exécuter votre code de programme et ne reprend son exécution normale qu'une fois son travail terminé.
Attention aux allocations de tas inutiles qui peuvent provoquer des pics GC.
Temps de récupération de mémoire chaque fois que possible
Si vous êtes certain qu'un gel de la récupération de mémoire n'affectera pas un point spécifique de votre jeu, vous pouvez déclencher la récupération de mémoire avec System.GC.Collect.
Consultez la section Comprendre la gestion automatique de la mémoire pour obtenir des exemples d'utilisation à votre avantage.
Utiliser l'Incremental Garbage Collector pour scinder la charge de travail du GC
Plutôt que de créer une seule et longue interruption pendant l'exécution de votre programme, la récupération de mémoire incrémentielle utilise plusieurs interruptions plus courtes qui répartissent la charge de travail sur de nombreuses images. Si le garbage collection provoque une fréquence d'image irrégulière, essayez cette option pour voir si elle peut réduire le problème des pics GC. Utilisez Profile Analyzer pour vérifier son intérêt pour votre application.
Notez que l'utilisation de la GC en mode incrémental ajoute des barrières de lecture-écriture à certains appels C#, ce qui entraîne des surcharges pouvant atteindre environ 1 ms par image de surcharge d'appel de programmation de scripts. Pour des performances optimales, l'idéal est de ne pas avoir d'allocations de GC dans les boucles principales du gameplay afin de ne pas avoir besoin de la GC incrémentielle pour une fréquence d'image fluide et de pouvoir masquer la GC là où un utilisateur ne la remarquera pas, par exemple lors de l'ouverture du menu ou du chargement d'un nouveau niveau.
Pour en savoir plus sur le Profileur de mémoire, consultez les ressources suivantes :

Téléchargez gratuitement l'ebook Guide ultime du profilage des jeux Unity pour obtenir tous les conseils et les bonnes pratiques.