378 votes

Taille de l'objet JavaScript

Je veux connaître la taille occupée par un objet JavaScript.

Prenez la fonction suivante -

function Marks()
{
  this.maxMarks = 100;
}

function Student()
{
  this.firstName = "firstName";
  this.lastName = "lastName";
  this.marks = new Marks();
}

Maintenant j'instancie l'étudiant

var stud = new Student();

pour que je puisse faire des choses comme

stud.firstName = "new Firstname";

alert(stud.firstName);

stud.marks.maxMarks = 200;

etc...

maintenant, stud L'objet occupera une certaine taille en mémoire. Il contient des données et d'autres objets.

Comment puis-je savoir combien de mémoire le stud l'objet occupe ?

quelque chose comme un sizeof() en JavaScript ?

Ce serait vraiment génial si je pouvais le trouver en un seul appel de fonction, par exemple

sizeof(stud)

P.S. J'ai cherché sur Internet pendant des mois - je ne l'ai pas trouvé (j'ai demandé dans quelques forums - pas de réponse).

212voto

tomwrong Points 2351

J'ai refactorisé le code dans mon fichier première réponse . J'ai supprimé la récursion et la surcharge de l'existence supposée.

function roughSizeOfObject( object ) {

    var objectList = [];
    var stack = [ object ];
    var bytes = 0;

    while ( stack.length ) {
        var value = stack.pop();

        if ( typeof value === 'boolean' ) {
            bytes += 4;
        }
        else if ( typeof value === 'string' ) {
            bytes += value.length * 2;
        }
        else if ( typeof value === 'number' ) {
            bytes += 8;
        }
        else if
        (
            typeof value === 'object'
            && objectList.indexOf( value ) === -1
        )
        {
            objectList.push( value );

            for( var i in value ) {
                stack.push( value[ i ] );
            }
        }
    }
    return bytes;
}

147voto

Guy Bedford Points 253

Le profileur de tas de Google Chrome vous permet d'inspecter l'utilisation de la mémoire des objets.

Vous devez être en mesure de localiser l'objet dans la trace, ce qui peut être délicat. Si vous épinglez l'objet au global Window, il est assez facile à trouver à partir du mode de listage "Containment".

Dans la capture d'écran ci-jointe, j'ai créé un objet appelé "testObj" sur la fenêtre. Je l'ai ensuite localisé dans le profileur (après avoir fait un enregistrement) et il montre la taille complète de l'objet et tout ce qu'il contient sous "retained size".

Plus de détails sur les ventilations de la mémoire ici - https://developers.google.com/chrome-developer-tools/docs/memory-analysis-101#object_sizes

Chrome profiler

Dans la capture d'écran ci-dessus, l'objet montre une taille retenue de 60. Je crois que l'unité est l'octet ici.

81voto

tomwrong Points 2351

Je viens d'écrire ceci pour résoudre un problème similaire (ou presque). Il ne fait pas exactement ce que vous recherchez, c'est-à-dire qu'il ne prend pas en compte la façon dont l'interpréteur stocke l'objet.

Mais, si vous utilisez V8, vous devriez obtenir une approximation assez correcte, car le prototypage génial et les classes cachées absorbent la majeure partie des frais généraux.

function roughSizeOfObject( object ) {

    var objectList = [];

    var recurse = function( value )
    {
        var bytes = 0;

        if ( typeof value === 'boolean' ) {
            bytes = 4;
        }
        else if ( typeof value === 'string' ) {
            bytes = value.length * 2;
        }
        else if ( typeof value === 'number' ) {
            bytes = 8;
        }
        else if
        (
            typeof value === 'object'
            && objectList.indexOf( value ) === -1
        )
        {
            objectList[ objectList.length ] = value;

            for( i in value ) {
                bytes+= 8; // an assumed existence overhead
                bytes+= recurse( value[i] )
            }
        }

        return bytes;
    }

    return recurse( object );
}

55voto

Andrei Karpushonak Points 2364

Hay una Module NPM pour obtenir la taille de l'objet vous pouvez l'installer avec npm install object-sizeof

  var sizeof = require('object-sizeof');

  // 2B per character, 6 chars total => 12B
  console.log(sizeof({abc: 'def'}));

  // 8B for Number => 8B
  console.log(sizeof(12345);

  var param = { 
    'a': 1, 
    'b': 2, 
    'c': {
      'd': 4
    }
  };
  // 4 one two-bytes char strings and 3 eighth-bytes numbers => 32B
  console.log(sizeof(param));

18voto

Bad Sector Points 508

C'est une méthode approximative, mais j'ai essayé deux fois avec des nombres différents et cela semble être cohérent.

Ce que vous pouvez faire, c'est d'essayer d'allouer une enorme nombre d'objets, comme un ou deux millions d'objets du type que vous voulez. Placez les objets dans un tableau pour empêcher le ramasseur d'ordures de les libérer (notez que cela ajoutera une légère surcharge de mémoire à cause du tableau, mais j'espère que cela n'aura pas d'importance et d'ailleurs si vous vous inquiétez de la présence d'objets en mémoire, vous les stockez quelque part). Ajoutez une alerte avant et après l'allocation et vérifiez dans chaque alerte combien de mémoire le processus Firefox prend. Avant d'ouvrir la page avec le test, assurez-vous que vous avez une nouvelle instance de Firefox. Ouvrez la page, notez l'utilisation de la mémoire après l'affichage de l'alerte "avant". Fermez l'alerte, attendez que la mémoire soit allouée. Soustrayez la nouvelle mémoire de l'ancienne et divisez-la par le nombre d'allocations. Exemple :

function Marks()
{
  this.maxMarks = 100;
}

function Student()
{
  this.firstName = "firstName";
  this.lastName = "lastName";
  this.marks = new Marks();
}

var manyObjects = new Array();
alert('before');
for (var i=0; i<2000000; i++)
    manyObjects[i] = new Student();
alert('after');

J'ai essayé cela sur mon ordinateur et le processus avait 48352K de mémoire lorsque l'alerte "avant" a été affichée. Après l'allocation, Firefox avait 440236K de mémoire. Pour 2 millions d'allocations, cela représente environ 200 octets pour chaque objet.

J'ai réessayé avec 1 million d'allocations et le résultat était similaire : 196 octets par objet (je suppose que les données supplémentaires dans 2 millions ont été utilisées pour Array).

Voici donc une méthode astucieuse qui pourrait vous aider. JavaScript ne fournit pas de méthode "sizeof" pour une raison : chaque implémentation JavaScript est différente. Dans Google Chrome, par exemple, la même page utilise environ 66 octets pour chaque objet (à en juger par le gestionnaire de tâches, du moins).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X