L'Unreal Engine 5 (UE5) étend les fonctions d'Unreal Insights grâce à l'ajout d'un outil de suivi amélioré de la mémoire et de la prise en charge du profilage à sa fonctionnalité Memory Insights. Les développeurs peuvent désormais accéder à tout moment à des informations plus détaillées sur l'allocation et la désallocation de mémoire, notamment les balises de mémoire de bas niveau (LLM) et les piles d'appels associées à chaque bloc de mémoire.
Memory Insights dispose d'un système de requête capable de trouver les allocations actives à un moment donné, de détecter les augmentations ou les diminutions d'utilisation de la mémoire, de différencier les allocations à court terme et à long terme, et d'identifier les fuites de mémoire.
L'UE 5.4 et les versions ultérieures prennent en charge le traçage de la mémoire avec des piles d'appels pour les projets Android.
Enregistrer une session
Pour commencer à utiliser Memory Insights en vue d'enregistrer une trace dans le canal de mémoire, procédez comme suit :
Exécuter ou compiler Unreal Insights
Accédez à Démarrer > Invite de commande et saisissez ce qui suit :
Engine\Binaries\Win64\UnrealInsights.exeVous pouvez également accéder au dossier Engine\Binaries\Win64 et double-cliquer sur le fichier UnrealInsights.exe pour l'exécuter.
Exécuter votre projet de jeu avec le traçage de la mémoire
Lancez l'invite de commande depuis votre système d'exploitation et exécutez l'échantillon de projet :
cd C:\MyEngineInstallLocation\
Samples\Games\MyGameSample\Binaries\Win64\MyGameSample.exe -trace=default,memoryPour enregistrer une session de votre projet, vous devez activer le canal de traçage de la mémoire dès le début du processus. Dans le cas contraire, il ne sera pas possible de lancer le traçage des événements d'allocation dans une session à connexion différée. Par ailleurs, si vous exécutez la trace sur un projet empaqueté, vous devez vous assurer qu'il est empaqueté en mode Développement.
Vous pouvez utiliser les commandes de trace metadata et assetmetadata pour fournir des options de filtre supplémentaires pour les noms de ressource et de classe. Par exemple, vous pouvez calculer le coût de l'allocation de mémoire par ressource ou par nom de classe.
Samples\Games\MyGameSample\Binaries\Win64\MyGameSample.exe -trace=default,memory,metadata,assetmetadataOuvrir votre trace à partir du navigateur de session d'Insights
Accédez de nouveau au navigateur de session d'Unreal Insights, puis double-cliquez sur le fichier .utrace pour l'ouvrir à des fins d'analyse dans la fenêtre Timing Insights d'Unreal Insights. Sélectionnez Menu > Memory Insights pour ouvrir la fenêtre Memory Insights.
Allocation de mémoire - Pistes de graphique
Unreal Insights capture des piles d'appels complètes pour chaque événement d'allocation afin de vous fournir une analyse de la mémoire allouée à votre projet. L'interface principale de Memory Insights est une chronologie affichant un aperçu de l'utilisation de la mémoire durant la session.
Le graphique de mémoire principale affiche la quantité totale de mémoire suivie dans votre projet, y compris les informations sur chaque balise collectées à partir du LLM. De plus, certains graphiques affichent le nombre total d'allocations en direct :
| Type de graphique | Couleur | Description |
|---|---|---|
Mémoire totale allouée | Bleu | Affiche la quantité totale de mémoire allouée à chaque instant, en fonction du suivi d'allocation détaillé. |
Nombre d'allocations en direct | Jaune | Affiche le nombre total d'allocations actives à chaque instant. |
Nombre d'événements d'allocation/de libération | Vert/Orange | Affiche le nombre d'événements d'allocation et de libération par unité, représenté sous forme d'"intervalle" de temps. |
Chacun de ces graphiques est basé sur un suivi détaillé des allocations. Tous commencent à une valeur de temps de 0 et ont une granularité d'environ 1 ms. Les autres graphiques avec les balises préfixées LLM (RenderTargets, SceneRender, UObject) sont basés sur un système d'exécution de suivi de mémoire de bas niveau.
Ces balises commencent à effectuer le suivi quelques secondes après le démarrage de la session et contiennent une granularité par image.
Par défaut, un horodatage est émis à chaque événement d'allocation/de libération de 4 096. Vous pouvez changer cette valeur en modifiant le paramètre MarkerSamplePeriod qui se trouve dans Engine/Source/Runtime/Core/Private/ProfilingDebugging/MemoryAllocationTrace.cpp. Par exemple, définir cette variable sur 0 émet un horodatage après chaque événement d'allocation/de libération.
La chronologie de Memory Insights prend en charge la superposition des pistes sur la vue de synchronisation. Lorsque vous utilisez la vue Memory Insights, quatre panneaux sont disponibles : Timing, Investigation, LLM Tags et Modules
Vue Timing
Vous pouvez cliquer sur Timing pour activer l'affichage de la fenêtre Timing View. Ici, vous pouvez observer et filtrer les données de performance de différentes pistes relatives à l'utilisation de la mémoire.
Panneau Investigation
Le panneau Investigation vous permet d'effectuer différentes requêtes sur les allocations.
Panneau LLM Tags
Le panneau LLM Tags contrôle la visibilité de différentes balises LLM (mémoire de bas niveau). Ces données sont directement issues de votre système d'exploitation.
Vous pouvez regrouper les balises LLM, les ressources et les fichiers sources. Par ailleurs, vous pouvez faire un clic droit sur n'importe quelle balise LLM dans le panneau LLM Tags et sélectionner Generate a New Color ou Edit Color pour personnaliser la couleur affichée à l'écran.
Les modules
Une fois les symboles de la pile d'appels résolus, le résultat est stocké dans le fichier cache. Vous pouvez afficher ces fichiers en cliquant sur Modules. Ce panneau permet d'ouvrir d'anciens fichiers de trace et d'utiliser des symboles.
Vous pouvez observer les colonnes selon le nombre de symboles, à savoir Discovered, Cached, Resolved et Failed. Les éléments de la liste qui ont échoué sont mis en surbrillance en rouge, et ceux qui ont été résolus correctement sont mis en surbrillance en vert. La couleur jaune indique que certains symboles ont été résolus, mais que d'autres ont échoué.
L'implémentation précédente du suivi de la mémoire est mise en œuvre dans la classe LowLevelMemTracker située dans le dossier Engine\Source\Runtime\Core\Public\HAL\LowLevelMemTracker.h. Le panneau LLM Tags et les graphiques LLM utilisent les données tracées directement à partir de ce système. Les données d'allocation détaillées proviennent d'une implémentation de trace distincte et spécifique.
Memory Insights est doté de nouvelles fonctionnalités de requête et d'une option de suivi des informations d'allocation de mémoire. Vous pouvez identifier les blocs de mémoire que l'UE5 alloue et libère dans certaines fenêtres temporelles, avant ou après un moment précis, ou vérifier la présence de fuites de mémoire. Vous pouvez accéder au système de requête en cliquant sur l'onglet Investigation après avoir ouvert un journal de trace.
La barre d'état située au bas du panneau Modules fournit des informations sur le nombre total de modules et sur leur taille.
Panneau Investigation - Requêtes d'allocation
Alors que la chronologie fournit une vue d'ensemble de l'utilisation de la mémoire, l'évaluation du comportement des allocations individuelles sur une période donnée s'effectue à l'aide de "requêtes". Une requête est définie par une règle et un ou plusieurs horodatages, tels que les étiquettes A et B.
Les règles de requête disponibles sont les suivantes :
| Règle de requête | Variable de temps | Description |
|---|---|---|
Active Alloc | A | Affiche toutes les allocations actives au temps A. |
Avant | A | Affiche toutes les allocations avant le temps A. |
Après | A | Affiche toutes les allocations après le temps A. |
Decline | A et B | Affiche toutes les allocations attribuées avant le temps A et libérées entre le temps A et le temps B. |
Growth | A et B | Affiche toutes les allocations attribuées entre les temps A et B et libérées après le temps B. |
Growth Vs Decline | A et B | Identifie les allocations de "croissance" (attribuées entre le temps A et le temps B et libérées après le temps B) et les allocations de "déclin" (attribuées avant le temps A et libérées entre le temps A et le temps B). Les allocations de déclin sont modifiées pour avoir une taille négative, de sorte que l'agrégation de taille affiche une variation entre A et B. Le résultat de cette requête est une comparaison de ce qui a été alloué au temps A et de ce qui a été alloué au temps B. Un groupe d'allocations de mémoire par balises ou piles d'appels affiche des variations (B - A) pour chaque groupe. |
Free Events | A et B | Affiche toutes les allocations libérées entre les temps A et B. |
Alloc Events | A et B | Affiche toutes les allocations attribuées entre les temps A et B. |
Short Living Allocs | A et B | Affiche toutes les allocations attribuées après le temps A et libérées avant le temps B. Vous pouvez utiliser cette règle pour identifier les allocations pouvant être cumulées ; autrement dit, cette règle identifie les allocations temporaires ou de courte durée. |
Long Living Allocs | A et B | Affiche toutes les allocations attribuées avant le temps A et libérées après le temps B. |
Memory Leaks | A, B et C | Affiche toutes les allocations attribuées entre les temps A et B et qui n'ont pas été libérées avant le temps C. Cela est utile pour identifier la mémoire devant être libérée à un moment donné, par exemple lors d'une transition de niveau. |
Limited Lifetime | A, B et C | Affiche toutes les allocations attribuées entre les temps A et B et libérées entre les temps B et C. |
Decline of Long Living Allocs | A, B et C | Affiche toutes les allocations attribuées avant le temps A et libérées entre les temps B et C. |
Specific Lifetime | A, B, C et D | Affiche toutes les allocations attribuées entre les temps A et B et libérées entre les temps C et D. |
Les requêtes sont effectuées en sélectionnant une règle et en faisant glisser les marqueurs étiquetés dans la chronologie vers les emplacements souhaités, ou en spécifiant un temps dans l'onglet Investigation.
Une fois les règles et les temps souhaités sélectionnés, cliquez sur le bouton Run Query dans l'onglet Investigation pour créer la requête.
En fonction de la requête et de l'ensemble de données capturées, l'exécution des requêtes peut prendre beaucoup de temps.
Vue de répartition des allocations
Lorsque la requête est exécutée, une nouvelle fenêtre s'affiche. Une fois la requête terminée, le tableau Alloc est rempli avec les résultats. Par défaut, les résultats s'affichent sous forme de liste simple.
Par défaut, chaque allocation affiche les informations suivantes :
Nombre
Taille
Balise LLM
Fonction (allocation)
Pile d'appels d'allocation
Fonction (libération)
Pile d'appels libre
Vous pouvez afficher des paramètres supplémentaires en faisant un clic droit sur un en-tête de tableau et en définissant les paramètres souhaités dans l'en-tête Column Visibility. De plus, vous pouvez placer le pointeur de la souris sur la puce à gauche de l'allocation pour afficher des détails supplémentaires.
Vous pouvez afficher des informations supplémentaires sur les allocations sélectionnées dans la barre d'état située au bas de l'écran, telles que le nombre total et la taille de la mémoire.
Tri
Cliquez sur l'en-tête du tableau pour trier la liste par colonnes.
| Colonne de tri | Description |
|---|---|
Allocation Hierarchy | Effectue le tri en fonction de la hiérarchie de l'arborescence d'allocation. |
Allocation Count | Effectue le tri en fonction du nombre d'allocations. |
Taille | Effectue le tri en fonction de la taille des allocations. |
Balise LLM | Effectue le tri en fonction de la balise LLM des allocations. |
Top Function (Callstack) | Effectue le tri selon la fonction supérieure résolue de la pile d'appels des allocations. |
CallStack Size | Nombre d'images de piles d'appels. |
Regroupement
Les options prédéfinies permettent de regrouper les allocations.
| Option prédéfinie | Description |
|---|---|
Valeur par défaut | Affiche les allocations par défaut. |
Detailed | Configure l'arborescence pour afficher des informations d'allocation détaillées. |
Heap | Détermine le mode d'utilisation des différents types de mémoire. Consultez la section Espaces d'adressage multiples. |
Taille | Identifie rapidement toutes les allocations importantes. |
Tags | Affiche les allocations par système. |
Asset (Package) | Configure l'arborescence pour afficher une répartition des allocations par métadonnées de paquet et de nom de ressource. |
Class Name | Configure l'arborescence pour afficher une répartition des allocations par nom de classe. |
Pile d'appels d'allocation | Configure l'arborescence pour afficher une répartition des allocations par pile d'appels. |
Inverted Alloc Callstack | Configure l'arborescence pour afficher une répartition des allocations par pile d'appels inversée. |
Pile d'appels libre | Configure l'arborescence pour afficher une répartition des allocations par pile d'appels de libération. |
Inverted Free Callstack | Configure l'arborescence pour afficher une répartition des allocations par pile d'appels de libération inversée. |
Address (4k Page) | Regroupe les allocations en pages de mémoire 4k en fonction de leur adresse.
|
Accédez à Hierarchy et cliquez sur All pour ouvrir un menu déroulant vous permettant de remplacer la vue Flat par défaut par une vue contenant des groupes supplémentaires.
Vous pouvez regrouper la hiérarchie à partir de la liste des options suivantes.
| Groupe de hiérarchie | Description |
|---|---|
Flat | Crée un groupe unique qui inclut tous les éléments. |
Taille | Regroupe les allocations en fonction de leur taille. |
Tag | Crée une arborescence basée sur la hiérarchie des balises. |
Callstack | Crée une arborescence basée sur la pile d'appels de chaque allocation. |
Inverted Callstack | Crée une arborescence basée sur la pile d'appels de chaque allocation. |
Heap | Crée une arborescence basée sur les tas. Les sous-groupes des groupes Allocs et Heap sont disponibles pour les tas racines. |
Unique Values - Event Distance | Crée un groupe pour chaque valeur de distance d'événement. |
Unique Values - Start Time | Crée un groupe pour chaque valeur d'heure de début. |
Unique Values - End Time | Crée un groupe pour chaque valeur d'heure de fin. |
Unique Values - Duration | Crée un groupe pour chaque valeur de durée. |
Unique Values - Address | Crée un groupe pour chaque valeur d'adresse. |
Unique Values - Memory Page | Crée un groupe pour chaque valeur de page mémoire. |
Unique Values - Size | Crée un groupe pour chaque valeur de taille. |
Unique Values - LLM Tag | Crée un groupe pour chaque valeur de balise LLM. |
Unique Values - Asset | Crée un groupe pour chaque valeur de ressource. |
Unique Values - Class Name | Crée un groupe pour chaque valeur de nom de classe. |
Unique Values - Top Function | Crée un groupe pour chaque valeur de fonction supérieure. |
Unique Values - Top Source File | Crée un groupe pour chaque valeur de fichier source supérieur. |
Unique Values - Callstack Size | Crée un groupe pour chaque valeur de taille de pile d'appels. |
Path Breakdown - LLM Tag | Crée une hiérarchie d'arborescence à partir de la structure des valeurs de chaîne de balise LLM. |
Path Breakdown - Asset | Crée une hiérarchie d'arborescence à partir de la structure des valeurs de chaîne de balise de ressource. |
Path Breakdown - Top Source File | Crée une hiérarchie d'arborescence à partir de la structure des valeurs de chaîne du fichier source supérieur. |
Utiliser le filtre avancé
La zone de texte de recherche permet de filtrer rapidement les résultats en fonction du texte du nœud hiérarchique. Vous pouvez filtrer de façon plus granulaire l'ensemble des allocations générées par la requête en vue d'isoler un groupe d'allocations en cliquant sur Filter Configurator en regard de la zone de texte de recherche.
Il est possible de créer des requêtes avancées en utilisant des groupes et les mots-clés AND/OR.
Résoudre les symboles de pile d'appels
Le traçage des symboles de pile d'appels à partir de votre projet s'effectue à l'aide des adresses du compteur ordinal. Lors de l'analyse, il convient de convertir ces adresses en chaînes lisibles accompagnées d'informations sur les fichiers sources correspondants.
Pour ce faire, Memory Insights doit avoir accès à la version correcte du fichier contenant les informations de débogage, c'est-à-dire soit un fichier .pdb soit un fichier .elf (selon la plateforme). Insights recherche le fichier correct selon la liste suivante :
Tous les nouveaux chemins saisis par l'utilisateur dans cette session.
Chemin de l'exécutable (s'il est disponible sur certaines plateformes, il est compilé dans le binaire).
Chemins à partir de la variable d'environnement
UE_INSIGHTS_SYMBOLPATH. Cette variable prend en charge les chemins séparés par des points-virgules.Chemins à partir de
_NT_SYMBOL_PATH.Chemins à partir du fichier de configuration des utilisateurs.
Une fois les symboles résolus, les résultats sont stockés dans le fichier de cache. Vous pouvez afficher ces fichiers en cliquant sur le panneau Modules. Pour ouvrir le fichier sélectionné, faites un clic droit dessus et choisissez l'une des options suivantes dans le menu déroulant.
Cela vous permet d'envoyer le fichier de trace à d'autres utilisateurs sans que ceux-ci aient besoin d'accéder à ces informations de débogage.
| Méthode de chargement | Description |
|---|---|
Load symbols from file | Permet de charger les symboles d'un module en spécifiant un fichier. En cas de réussite, il tente de charger d'autres modules qui ont échoué à partir du même répertoire. |
Load symbols from directory | Permet de charger les symboles d'un module en spécifiant le répertoire. En cas de réussite, il tente de charger d'autres modules qui ont échoué à partir du même répertoire. |
La résolution de symbole est actuellement disponible sur Win64, XB1/XSX, PS4/PS5 et Switch.
Espaces d'adressage multiples
Le traçage de la mémoire effectue un suivi de la mémoire dans différents tas. D'un point de vue conceptuel, toute allocation doit appartenir à un tas racine qui représente un type de mémoire. Par exemple, sur les plateformes de bureau, l'un des tas racines correspond à la mémoire système et l'autre à la mémoire vidéo de la carte graphique. Chaque tas racine dispose de son propre espace d'adressage. Sous chaque tas racine, diverses allocations de tas sont créées pouvant accueillir des allocations. Bien qu'en général il s'agisse d'allocations de mémoire virtuelle qui sauvegardent les allocations, les allocateurs de type bloc peuvent également être représentés par des allocations de tas. Cela permet d'analyser l'utilisation de ces blocs de mémoire.
Exporter un instantané
Vous pouvez exporter les allocations de mémoire au format .csv ou .tsv en faisant un clic droit dessus et en choisissant Exporter l'instantané dans le menu contextuel.