Résoudre les problèmes de mémoire

Découvrez comment utiliser Chrome et les outils de développement pour détecter les problèmes de mémoire qui affectent les performances des pages, y compris les fuites de mémoire, les surplus de mémoire et les récupérations fréquentes de mémoire.

Résumé

  • Utilisez le gestionnaire de tâches Chrome pour connaître la quantité de mémoire actuellement utilisée par votre page.
  • Visualisez l'utilisation de la mémoire au fil du temps avec les enregistrements de Vos trajets.
  • Identifiez les arborescences DOM dissociées (une cause fréquente de fuite de mémoire) avec les instantanés de tas de mémoire.
  • Découvrez quand une nouvelle mémoire est allouée dans votre tas de mémoire JS grâce aux enregistrements de la chronologie d'allocation.

Présentation

Dans l'esprit du modèle de performances RAIL, vous devez concentrer vos efforts sur l'optimisation des performances. vos utilisateurs.

Les problèmes de mémoire sont importants, car ils sont souvent perçus par les utilisateurs. Les utilisateurs peuvent percevoir la mémoire de différentes manières:

  • Les performances d'une page se dégradent progressivement au fil du temps. Il peut s'agir d'un symptôme une fuite de mémoire. Une fuite de mémoire se produit lorsqu'un bug de la page entraîne une utilisation progressive de plus en plus plus de mémoire au fil du temps.
  • Les performances d'une page sont systématiquement mauvaises. Il peut s'agir d'un symptôme de gonflement de la mémoire. Infos mémorisées Surcharge, on parle de surcharge de mémoire lorsqu'une page utilise plus de mémoire que nécessaire pour obtenir une vitesse optimale.
  • Les performances d'une page sont retardées ou semblent être fréquemment mises en veille. Il s’agit peut-être d’un symptôme des récupérations de mémoire fréquentes. On parle de récupération de mémoire lorsque le navigateur récupère de la mémoire. Le navigateur décide quand cela se produit. Pendant les collections, toutes les exécutions de scripts sont suspendues. Si le navigateur la récupération de mémoire, l'exécution du script va s'interrompre régulièrement.

Mémoire saturée: combien coûte "trop" ?

Une fuite de mémoire est facile à définir. Si un site utilise de plus en plus de mémoire, une fuite. Toutefois, il est un peu plus difficile d'identifier les problèmes de mémoire gonflée. Qu'entend-on par "utiliser trop de mémoire" ?

Il n'y a pas de chiffres précis ici, car les capacités diffèrent selon les appareils et les navigateurs. La même page qui fonctionne correctement sur un smartphone haut de gamme peut planter sur un smartphone d'entrée de gamme.

L'essentiel ici est d'utiliser le modèle RAIL et de se concentrer sur vos utilisateurs. Découvrez les appareils populaires avec vos utilisateurs, puis testez votre page sur ces appareils. Si l'expérience est cohérente de mauvaise qualité, il se peut que la page dépasse les capacités de mémoire de ces appareils.

Surveiller l'utilisation de la mémoire en temps réel avec le gestionnaire de tâches Chrome

Utilisez le gestionnaire de tâches Chrome comme point de départ pour rechercher les problèmes de mémoire. Le gestionnaire de tâches est un moniteur en temps réel qui vous indique la quantité de mémoire actuellement utilisée par une page.

  1. Appuyez sur Maj+Échap ou accédez au menu principal de Chrome et sélectionnez Plus d'outils > Gestionnaire de tâches pour ouvrez le gestionnaire de tâches.

    Ouverture du gestionnaire de tâches

  2. Effectuez un clic droit sur l'en-tête du tableau dans le gestionnaire des tâches, puis activez la mémoire JavaScript.

    Activation de la mémoire JS

Ces deux colonnes vous indiquent des informations différentes sur l'utilisation de la mémoire par votre page:

  • La colonne Memory (Mémoire) représente la mémoire native. Les nœuds DOM sont stockés en mémoire native. Si cette augmente, les nœuds DOM sont créés.
  • La colonne Mémoire JavaScript représente le tas de mémoire JS. Cette colonne contient deux valeurs. La la valeur qui vous intéresse est le nombre réel (le nombre entre parenthèses). Le numéro en direct représente la quantité de mémoire utilisée par les objets accessibles sur votre page. Si ce nombre est augmente, soit de nouveaux objets sont créés, soit les objets existants grandissent.

Visualiser les fuites de mémoire avec les enregistrements de performances

Vous pouvez également utiliser le panneau "Performances" comme autre point de départ de votre investigation. Spectacle vous aide à visualiser l'utilisation de la mémoire d'une page au fil du temps.

  1. Ouvrez le panneau Performances dans les outils de développement.
  2. Cochez la case Memory (Mémoire).
  3. Réalisez un enregistrement.

Pour illustrer les enregistrements de mémoire Performance, prenons l'exemple du code ci-dessous:

var x = [];

function grow() {
  for (var i = 0; i < 10000; i++) {
    document.body.appendChild(document.createElement('div'));
  }
  x.push(new Array(1000000).join('x'));
}

document.getElementById('grow').addEventListener('click', grow);

Chaque fois que l'utilisateur appuie sur le bouton référencé dans le code, 10 000 nœuds div sont ajoutés au corps du document, et une chaîne d'un million de caractères x est transmise au tableau x. L'exécution de ce code produit un enregistrement de la chronologie, semblable à la capture d'écran suivante:

exemple de croissance simple

Tout d'abord, une explication de l'interface utilisateur. Le graphique HEAP dans le volet Overview (Aperçu) (ci-dessous) NET) représente le tas de mémoire JS. Sous le volet Aperçu se trouve le volet Compteur. Vous pouvez alors voir l'utilisation de la mémoire répartie par tas de mémoire JS (comme pour le graphique HEAP dans le volet Aperçu) ; les documents, les nœuds DOM, les écouteurs et la mémoire GPU. Le fait de décocher une case permet de la masquer dans le graphique.

Maintenant, analyse du code par rapport à la capture d'écran. Si vous examinez le compteur de nœuds (le nombre graphique vert), vous constatez qu'il correspond parfaitement au code. Le nombre de nœuds augmente pas à pas. Vous pouvez supposer que chaque augmentation du nombre de nœuds est un appel à grow(). JavaScript le graphique de segment de mémoire (le graphique bleu) n'est pas aussi simple. Conformément aux bonnes pratiques, la première baisse est en réalité une récupération forcée de mémoire (réussi en appuyant sur le bouton collecter la mémoire). En tant que l'enregistrement progresse, vous pouvez voir que la taille du tas de mémoire JS augmente. Ceci est tout à fait naturel et attendu : Le code JavaScript crée des nœuds DOM à chaque clic sur un bouton et effectue un travail important lorsqu'il crée la chaîne d'un million de caractères. L'élément clé ici est que le tas de mémoire JS se termine plus élevée qu'au début (le "début" est ici le point suivant la récupération forcée de mémoire). Dans Dans le monde réel, si vous constatiez une augmentation de la taille des tas de mémoire ou des nœuds JS, potentiellement une fuite de mémoire.

Détectez les fuites de mémoire de l'arborescence DOM dissociée avec les instantanés de tas de mémoire.

La récupération de mémoire d'un nœud DOM ne peut être effectuée que s'il n'existe aucune référence à celui-ci dans les l'arborescence DOM ou le code JavaScript. Un nœud est dit "détaché" lorsqu'il est supprimé de l'arborescence DOM, certains éléments JavaScript s'y réfèrent toujours. Les nœuds DOM dissociés sont une cause fréquente de fuite de mémoire. Ce explique comment utiliser les outils de développement. des profileurs de segments de mémoire pour identifier les nœuds dissociés.

Voici un exemple simple de nœuds DOM dissociés.

var detachedTree;

function create() {
  var ul = document.createElement('ul');
  for (var i = 0; i < 10; i++) {
    var li = document.createElement('li');
    ul.appendChild(li);
  }
  detachedTree = ul;
}

document.getElementById('create').addEventListener('click', create);

Cliquez sur le bouton référencé dans le code pour créer un nœud ul avec dix enfants li. Ces nœuds référencés par le code, mais n'existent pas dans l'arborescence DOM, et sont donc dissociés.

Les instantanés de tas de mémoire sont un moyen d'identifier les nœuds dissociés. Comme leur nom l'indique, les instantanés de tas de mémoire vous montrent la façon dont la mémoire est répartie entre les objets JavaScript et les nœuds DOM de votre page au moment où un instantané.

Pour créer un instantané, ouvrez les outils de développement, accédez au panneau Mémoire, puis sélectionnez le tas de mémoire. Case d'option d'instantané, puis appuyez sur le bouton Prendre un instantané.

prendre un instantané du segment de mémoire

Le traitement et le chargement de l'instantané peuvent prendre un certain temps. Une fois qu'il est terminé, sélectionnez-le à gauche (nommé HEAP SNAPSHOTS) ;

Saisissez Detached dans la zone de texte Class filter (Filtre de classe) pour rechercher des arborescences DOM dissociées.

le filtrage des nœuds dissociés

Développez les carats pour examiner un arbre détaché.

enquêter sur un arbre détaché

Les nœuds surlignés en jaune ont une référence directe à eux dans le code JavaScript. Nœuds mis en évidence n'ont pas de références directes. Ils ne sont actifs que parce qu'ils font partie du nœud jaune arborescence. En général, vous devez vous concentrer sur les nœuds jaunes. Corrigez votre code pour que le nœud jaune ne soit pas en vie plus longtemps que nécessaire, et vous vous débarrassez également des nœuds rouges qui font partie dans l'arborescence du nœud jaune.

Cliquez sur un nœud jaune pour l'examiner plus en détail. Le volet Objets contient des informations sur le code qui y fait référence. Par exemple, la capture d'écran ci-dessous montre que la variable detachedTree fait référence au nœud. Pour corriger cette fuite de mémoire, doit étudier le code qui utilise detachedTree et s'assurer qu'il supprime sa référence au nœud. lorsque vous n'en avez plus besoin.

enquêter sur un nœud jaune

Identifier les fuites de mémoire du tas de mémoire JS à l'aide des délais d'allocation

La chronologie d'allocation est un autre outil qui peut vous aider à détecter les fuites de mémoire dans votre tas de mémoire JS.

Pour illustrer la chronologie d'allocation, considérez le code suivant:

var x = [];

function grow() {
  x.push(new Array(1000000).join('x'));
}

document.getElementById('grow').addEventListener('click', grow);

Chaque fois que le bouton référencé dans le code est poussé, une chaîne d'un million de caractères est ajouté au tableau x.

Pour enregistrer une chronologie d'allocation, ouvrez les outils de développement, accédez au panneau Profiles (Profils), sélectionnez l'option Record (Enregistrer) Case d'option "Allocation Timeline", appuyez sur le bouton Start (Démarrer), effectuez l'action que vous pensez est à l'origine de la fuite de mémoire, puis appuyez sur le bouton Arrêter l'enregistrement (bouton d&#39;arrêt d&#39;enregistrement) lorsque vous avez terminé.

Pendant l'enregistrement, notez si des barres bleues s'affichent sur la chronologie d'allocation, comme dans ci-dessous.

nouvelles allocations

Ces barres bleues représentent les nouvelles allocations de mémoire. Ces nouvelles allocations de mémoire sont vos candidats des fuites de mémoire. Vous pouvez zoomer sur une barre pour filtrer le volet Constructeur et n'afficher que les objets ont été allouées au cours de la période spécifiée.

chronologie d&#39;allocation avec zoom

Développez l'objet et cliquez sur sa valeur pour afficher plus de détails le concernant dans le volet Objet. Pour Dans la capture d'écran ci-dessous, en affichant les détails de l'objet nouvellement alloué, vous pourrez voir qu'elle a été allouée à la variable x dans le champ d'application Window.

détails de l&#39;objet

Examiner l'allocation de mémoire par fonction

Utilisez le type Échantillonnage d'allocation dans le panneau Mémoire pour afficher l'allocation de mémoire par fonction JavaScript.

Profileur d&#39;allocation d&#39;enregistrements

  1. Sélectionnez la case d'option Allocation Sampling (Échantillonnage d'allocation). Si un nœud de calcul figure sur la page, Vous pouvez la sélectionner comme cible de profilage à l'aide du menu déroulant à côté du bouton Start (Démarrer).
  2. Appuyez sur le bouton Start (Démarrer).
  3. Effectuez les actions qui vous intéressent sur la page.
  4. Appuyez sur le bouton Arrêter lorsque vous avez terminé.

Les outils de développement présentent la répartition de l'allocation de mémoire par fonction. La vue par défaut est En bas (en bas) Up), qui affiche en haut les fonctions ayant alloué le plus de mémoire.

Profil d&#39;allocation

Détecter les récupérations de mémoire fréquentes

Si votre page semble se mettre en pause fréquemment, vous rencontrez peut-être des problèmes de récupération de mémoire.

Vous pouvez utiliser les enregistrements de mémoire du gestionnaire de tâches Chrome ou de Vos trajets pour repérer les déchets fréquents des collections. Dans le gestionnaire des tâches, les valeurs de mémoire ou de mémoire JavaScript qui augmentent ou diminuent fréquemment représentent des récupérations de mémoire fréquentes. Dans les enregistrements de Vos trajets, hausse et baisse fréquentes Les graphiques de tas de mémoire ou de nombre de nœuds JS indiquent les récupérations de mémoire fréquentes.

Une fois le problème identifié, vous pouvez utiliser un enregistrement du calendrier d'allocation pour savoir où de mémoire est allouée et quelles fonctions sont à l'origine de ces allocations.