L'Unreal Engine (UE) utilise un nettoyage de la mémoire par marquage-balayage pour gérer la mémoire des UObjects. Pour les applications temps-réel souples, les nettoyages de mémoire ont toujours présenté un inconvénient majeur : le risque de générer des problèmes de gameplay pendant que le nettoyage de mémoire évalue quelle quantité de mémoire des objets est récupérable. Dans l'UE, ce processus est appelé analyse d'accessibilité. L'UE s'appuie sur cette phase de nettoyage de la mémoire pour s'exécuter en une seule image, ce qui interrompt temporairement tout traitement des UObjects (en particulier le gameplay). Plus l'analyse d'accessibilité doit analyser d'objets, plus l'interruption est longue, ce qui peut engendrer des problèmes de gameplay visibles. Les programmeurs peuvent éviter ces problèmes de plusieurs manières, notamment les suivantes :
Limiter le budget d'UObject.
Utiliser des pools d'UObject.
Désactiver le nettoyage de la mémoire pendant le gameplay normal.
Toutefois, ces solutions ont tendance à accroître la complexité du code et le coût global du projet.
Analyse d'accessibilité incrémentielle
L'UE améliore ce système à l'aide de l'analyse d'accessibilité incrémentielle. Les utilisateurs peuvent maintenant répartir la phase d'analyse d'accessibilité du nettoyage de la mémoire sur plusieurs images, avec une limite de temps souple et configurable par image. Le moteur suit les références UObject entre les itérations d'accessibilité par le biais des propriétés TObjectPtr. Ainsi, toute assignation à une UPROPERTY exposée par TObjectPtr marque immédiatement l'objet comme accessible pendant le nettoyage de la mémoire. Ce comportement est également appelé barrière d'écriture du nettoyage de mémoire.
Le moteur a déjà été converti pour utiliser TObjectPtr au lieu des pointeurs C++ bruts partout où aux endroits qui exposent les UObjects au nettoyage de la mémoire, notamment les fonctions AddReferencedObjects. d'UObject ou de FGCObject. Pour utiliser l'analyse d'accessibilité incrémentielle dans les projets conçus avec l'Unreal Engine, il est crucial de convertir toutes les instances UPROPERTY pour qu'elles utilisent TObjectPtr au lieu de C++ brut ; sans quoi, le nettoyage de la mémoire risque de récupérer une partie de la mémoire des UObjects trop tôt. Initialement, nous avons publié cette fonctionnalité à titre expérimental, car il est toujours possible que la phase d'analyse d'accessibilité dépasse la durée spécifiée.
Activer l'analyse d'accessibilité incrémentielle
L'analyse d'accessibilité incrémentielle peut être activée avec les variables de console suivantes, lorsqu'elles sont ajoutées au fichier DefaultEngine.ini de votre projet :
[ConsoleVariables]
gc.AllowIncrementalReachability=1 ; enables Incremental Reachability Analysis
gc.AllowIncrementalGather=1 ; enables Incremental Gather Unreachable Objects
gc.IncrementalReachabilityTimeLimit=0.002 ; sets the soft time limit to 2msVariables de console supplémentaires
Vous pouvez également utiliser des variables de console pour réaliser des tests de résistance et à des fins de débogage :
| Variable de console | Description | Type |
|---|---|---|
| Retarder l'analyse d'accessibilité du nombre d'images spécifié. Utilisée pour tester la barrière CG. |
|
| Exécuter un test une fois l'analyse d'accessibilité terminée pour s'assurer qu'aucun objet accessible (valide) ne référence un objet accessible (bientôt détruit). | 0 : désactivé, 1 : activé |
| Redémarrer le nettoyage de la mémoire incrémentiel après la fin du précédent. | 0 : désactivé, 1 : activé |
Comparatif de performances
Vous trouverez plus bas une visualisation Unreal Insights du graphique de performances d'un exemple de projet avec l'accessibilité incrémentielle désactivée. La ligne bleue représente la durée totale de l'image et la ligne orange le temps consacré à l'analyse d'accessibilité. L'Unreal Insights trace une ligne graphique continue entre des événements distincts séparés par plusieurs images ; même si le nettoyage de la mémoire semble s'exécuter sur toute la chronologie, il ne s'exécute que sur une seule image à la fois.
Dans la première image de la comparaison de graphique suivante, vous pouvez observer un pic à chaque exécution du nettoyage de la mémoire (indiqué par les étiquettes CG en haut de la chronologie).
Dans la deuxième image, avec l'accessibilité incrémentielle activée, vous pouvez constater que les pics de latence du GC ont disparu et que l'accessibilité incrémentielle est désormais répartie sur plusieurs images (représentée par des barres vertes plus larges).
Limites connues
L'accessibilité incrémentielle n'est pas totalement exempte de risque pour les threads. Dans certaines circonstances, un objet manipulé sur un thread de travail ne sera pas marqué comme accessible pendant que le nettoyage de mémoire analyse le graphique UObject. Cela peut entraîner un nettoyage prématuré de l'objet. Nous recommandons d'activer l'accessibilité incrémentielle dans les compilations monothread (par ex. les serveurs dédiés).