Vue "Dominants"

La vue "Dominants" est une des nouveautés de Firefox 46.

À partir de Firefox 46, l'outil Mémoire inclut une nouvelle vue nommée "Dominants". Celle-ci est utile pour comprendre la "Taille retenue" des objets d'un site : il s'agit de la taille des objets eux-mêmes ainsi que la taille des objets qu'ils gardent en vie par référence.

Si vous n'êtes pas familier avec la "profondeur", la "taille retenue" et les Dominants, il est recommandé de lire l'article sur les concepts des Dominants.

UI des Dominants

Pour afficher la vue des Dominants, il faut sélectionner "Dominants" dans le menu déroulant "Afficher" :

Dans la partie principale de l'UI, la première ligne est nommée "Racines GC". En dessous de cette ligne, il y a une ligne pour :

  • Chaque noeud racine GC. Dans Gecko, il y a plus d'un graph, et donc plus d'une racine. Il peut y avoir beaucoup de racines (souvent temporaires). Par exemple les variables allouées sur la stack ont besoin d'être enracinées
  • Chaque autre noeud qui est référencé depuis deux racines différentes (vu que dans ce cas, aucune des deux racines ne le domine).

Pour chacune de ces lignes, seront affichés :

  • La taille retenue du noeud, en octets et en pourcentage total.
  • La profondeur du noeud en octets et en pourcentage total.
  • Le nom du noeud et son adresse mémoire.

Si le noeud domine d'autres noeuds, alors la "taille retenue" est plus grande que la "profondeur", et le nom du noeud possède une une icône en forme de triangle. Cette icône permet de développer le noeud pour afficher les noeuds qui sont directement dominés par ce noeud (il s'agit des autres objets retenus directement par cet objet) :

 
Il est possible d'utiliser Alt + clic pour étendre le graph entier d'un noeud.

Pile d'allocations

L'Allocation Stack affiche exactement ou dans le code les objets sont alloués.

Pour l'activer, il faut cocher la case "Enregistrer les piles d'allocations" avant de lancer le coder qui alloue les objets. Il faut ensuite prendre une capture, puis sélectionner "Allocation Stack" dans le menu déroulant "Nommer selon".

Maintenant, le nom du noeud contient le nom de la fonction qui l'a alloué, ainsi que le fichier, la ligne et la position exacte d'ou dans la fonction l'allocation a été faite. Cliquer sur le nom du fichier ouvrira cette position dans le Débogueur.

Parfois, une ligne nommée "(no stack available)" est présente. Les piles d'allocations ne sont actuellement enregistrées que pour les objets, pas pour les tableaux, les strings ou les structures internes.here.

Exemple

Pour tester l'outil, il est plus simple d'utiliser un exemple.

L'exemple est disponible à l'adresse : https://mdn.github.io/performance-scenarios/js-allocs/alloc.html. Le code en question est le suivant :

var MONSTER_COUNT = 5000;
var MIN_NAME_LENGTH = 2;
var MAX_NAME_LENGTH = 48;

function Monster() {

  function randomInt(min, max) {
      return Math.floor(Math.random() * (max - min + 1)) + min;
    }

  function randomName() {
    var chars = "abcdefghijklmnopqrstuvwxyz";
    var nameLength = randomInt(MIN_NAME_LENGTH, MAX_NAME_LENGTH);
    var name = "";
    for (var j = 0; j < nameLength; j++) {
      name += chars[randomInt(0, chars.length-1)];
    }
    return name;
  }

  this.name = randomName();
  this.eyeCount = randomInt(0, 25);
  this.tentacleCount = randomInt(0, 250);
}

function makeMonsters() {
  var monsters = {
    "friendly": [],
    "fierce": [],
    "undecided": []
  };

  for (var i = 0; i < MONSTER_COUNT; i++) {
    monsters.friendly.push(new Monster());
  }

  for (var i = 0; i < MONSTER_COUNT; i++) {
    monsters.fierce.push(new Monster());
  }

  for (var i = 0; i < MONSTER_COUNT; i++) {
    monsters.undecided.push(new Monster());
  }

  console.log(monsters);
}

var makeMonstersButton = document.getElementById("make-monsters");
makeMonstersButton.addEventListener("click", makeMonsters);

La page contient un bouton lorsque celui-ci est appuyé, le code crée des monstres. Spécifiquement :

  • Le code crée un objet avec trois propriétés, chacune étant un tableau : un pour les monstres féroces, un pour les monstres gentils et un pour les monstres qui n'ont pas encore décidés.
  • Le code crée 5000 monstres aléatoires dans chaque tableau. Chaque monstre a :
    • une string, contentant son nom
    • un nombre qui représente le nombre d'yeux qu'il possède
    • un nombre qui représente le nombre de tentacules qu'il possède

Ainsi, la structure de la mémoire allouée sur la heap JavaScript est un objet contenant trois tableaux contenant chacun 5000 objets (les monstres) chaque objet contient une string et deux int :

Pour voir à quoi cela ressemble avec la vue "Dominants", il faut :

  • Charger la page
  • Activer l'outil Mémoire dans les Options, s’il n'est pas encore activé.
  • Ouvir l'outil Mémoire
  • Cocher la case " Enregistrer les piles d'allocations"
  • Appuyer sur le bouton "Make monsters!"
  • Prendre une capture
  • Passer à la vue "Dominants"

Il est alors possible de voir que le premier objet, la racine GC tout en haut retient prés de de 90% de l'utilisation de la mémoire :

Si l'objet est étendu, les trois tableaux seront affichés, et ceux-ci peuvent être également étendus pour afficher les objets (monstres) qu'ils contiennent. Chaque monstre à une profondeur relativement petite, celle-ci inclut le nombre d'yeux, le nombre de tentacules et le petit nom du monstre :

Enfin, si le tri est passé à "Allocation Stack", il est possible de voir d'où les objets sont alloués, et d'ouvrir le Débogueur à ce endroit précis :

Étiquettes et contributeurs liés au document

 Contributeurs à cette page : maximelore
 Dernière mise à jour par : maximelore,