Toute application Web d’une taille suffisamment importante atteindra très probablement le point où elle consommera plus de mémoire que prévu. DevTools peut inviter un développeur à commencer à prendre des instantanés du tas de mémoire. Cela lui permettra de voir quels objets sont stockés en mémoire. DevTools peut montrer dans le volet Retainers quels sont les objets qui font qu’un objet reste en mémoire. Tout objet sans retenue peut être jeté par le collecteur de déchets du navigateur. Cela réduit l’utilisation de la mémoire.
Toutefois, la fenêtre Retainers n’est utile que si elle fonctionne correctement. Ces derniers mois, les ingénieurs de Microsoft Teams ont reçu de nombreux rapports de bogue. Ils décrivent des cas où DevTools a affiché les retenues sans aucune logique. Les développeurs d’applications Web étaient incapables de prendre des mesures pour supprimer ces éléments de retenue.
Merci à tous ceux qui ont porté ces problèmes à notre attention. Nous avons corrigé ces bogues (détails ici), mais nous savons qu’il peut y en avoir d’autres. Veuillez nous faire savoir si quelque chose ne va pas. Le bouton de feedback de DevTools est le moyen le plus simple de nous joindre.
DevTools propose un bouton pour « Envoyer un commentaire ».
Veuillez noter que les informations suivantes ne sont pas spécifiques à Microsoft Edge. Cependant, nous avons corrigé des problèmes dans le moteur JavaScript du navigateur (V8). Ce code est partagé avec Chrome, Electron et Node. Tous les produits bénéficieront également de ces corrections.
Nager dans de fausses voies de rétention
Supposons que vous utilisiez la page new-tab de Microsoft Edge edge://newtab et que vous vouliez comprendre pourquoi observe() est maintenu en vie. Pour ouvrir DevTools, cliquez sur F12 et naviguez dans l’onglet Mémoire. Sélectionnez l’objet que vous souhaitez visualiser dans le panneau supérieur. La version 94 de Microsoft Edge vous montrera quatre mémoires pour effectuer cette fonction.
DevTools a un onglet Mémoire
En élargissant encore ce chemin, vous verriez que le FeedbackVector est une structure de données interne qui enregistre des données sur les fonctions qui ont été appelées. En élargissant encore un peu ce chemin, vous verriez que le FeedbackVector appartient à une autre fonction, HTMLElement.attachShadow() :
Le chemin du FeedbackVector a été développé dans le listing des Retainers.
La fonction conserve un certain nombre d’éléments V8 internes que vous ne pouvez pas contrôler et qui, à leur tour, préservent la fonction originale observe(). Puisque tout est interne au V8, comment pouvez-vous rompre cette connexion ?
Si vous ne le pouvez pas, cela signifie que le bug est présent. Soit la mémoire de V8 est épuisée, soit la fenêtre Retainers est erronée. Ces deux problèmes sont extrêmement importants pour nous. Dans ce cas précis, Microsoft Edge affichait des provisions incorrectes. Ce problème a été résolu dans Microsoft Edge 99. Voici la liste des solutions correctes pour les retenues de garantie :
DevTools a maintenant la liste correcte de Retainers.
Les grandes applications ont une arborescence de retenues qui est à la fois étendue et large. De nombreuses enquêtes sur l’utilisation de la mémoire sont bloquées par ce nombre de faux chemins. Ce problème était si répandu que nos amis de Microsoft Teams ont utilisé une solution de contournement. Elle capture des informations supplémentaires pendant la phase de collecte des déchets de V8 et met en évidence le seul chemin de rétention qui est réellement vrai.
Gardez-le fixé
Les développeurs doivent avoir confiance en DevTools. Nous créons donc une solution automatisée pour éviter les régressions qui conduisent à de faux chemins de rétention. La perspicacité de Microsoft Teams a montré que l’instantané du tas doit correspondre aux comportements de marquage du garbage collector. Nous avons donc proposé un code de validation pour comparer les bords sortants de chaque nœud dans la photo du tas avec les codes réels du ramasseur d’ordures et faire planter le processus en cas de discordance.
Cette validation sera incluse dans les builds de débogage, y compris celles qui sont utilisées pour les tests automatisés quotidiens. Nous pouvons rapidement trouver et corriger tout problème causant une discordance entre le comportement de l’instantané et celui du garbage collector.
Données de désoptimisation
Les ingénieurs de Microsoft Teams ont trouvé de grands graphiques d’objets qui n’étaient pas retenus par des objets nommés « (code Deopt Data ») », comme celui illustré ci-dessous.
Une liste de retenues qui sont liées aux « données de désoptimisation ».
Les DevTools montrent que les fonctions JavaScript retiennent des objets internes à V8, similaires aux faux chemins de FeedbackVector. Ces objets ne sont pas sous le contrôle du développeur, qui retient alors une autre opération JavaScript. DevTools dans ce cas, cependant, était plus précis que le précédent. Il a décrit avec précision ce qui se passait à l’intérieur de V8, qui était en fait une fuite de mémoire. Ce problème a été résolu dans la version 98 de Microsoft Edge.
Registres de finalisation
Dans un autre excellent rapport de Microsoft Teams, nous avons constaté qu’un grand nombre d’objets FinalizationRegistry étaient retenus directement par d’autres FinalizationRegistries, ce qui entraînait une utilisation élevée de la mémoire :
Une liste d’objets FinalizationRegistry retenus par d’autres FinalizationRegistries.
Il s’agissait d’une autre fuite de mémoire interne à la V8, que nous avons également corrigée.
Fermons
Nous tenons à ce que les développeurs Web disposent des outils nécessaires pour identifier et résoudre les problèmes d’utilisation abusive de la mémoire. Le moteur JavaScript ne doit pas laisser fuir de mémoire et représenter avec précision l’état du tas lors des instantanés vers DevTools.
Nous veillerons à ce que tout ce qui figure dans le volet Retainers reflète fidèlement ce qui se passe réellement et qu’il n’y ait pas de fuites de données internes dans le V8. Nous avons résolu les problèmes qui nous sont connus, mais nous apprécierions vos commentaires sur tout autre problème.