我想知道JavaScript对象占用的大小。

取以下函数:

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

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

现在我实例化这个学生:

var stud = new Student();

这样我就可以做

stud.firstName = "new Firstname";

alert(stud.firstName);

stud.marks.maxMarks = 200;

etc.

现在,stud对象将在内存中占据一定大小。它有一些数据和更多的对象。

我如何找出有多少内存stud对象占用?类似于JavaScript中的sizeof() ?如果我能在一个函数调用中找到它,比如sizeof(stud),那就太棒了。

我已经在网上搜索了几个月了——没有找到它(在几个论坛上被问到——没有回复)。


当前回答

我写这个只是为了解决一个类似的问题。它不完全做你可能要找的,即它不考虑解释器如何存储对象。

但是,如果你正在使用V8,它应该给你一个相当不错的近似,因为出色的原型和隐藏类舔掉了大部分开销。

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 );
}

其他回答

对不起,我不能评论,所以我只能从明天开始继续工作。 此增强版本不会对对象进行多次计数,因此不会出现无限循环。 另外,我认为一个物体的键也应该粗略地计算。

function roughSizeOfObject( value, level ) {
    if(level == undefined) level = 0;
    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' ) {
        if(value['__visited__']) return 0;
        value['__visited__'] = 1;
        for( i in value ) {
            bytes += i.length * 2;
            bytes+= 8; // an assumed existence overhead
            bytes+= roughSizeOfObject( value[i], 1 )
        }
    }

    if(level == 0){
        clear__visited__(value);
    }
    return bytes;
}

function clear__visited__(value){
    if(typeof value == 'object'){
        delete value['__visited__'];
        for(var i in value){
            clear__visited__(value[i]);
        }
    }
}

roughSizeOfObject(a);

有同样的问题。我在谷歌上搜索,我想与stackoverflow社区分享这个解决方案。

重要的是:

我使用了Yan Qing在github上分享的功能 https://gist.github.com/zensh/4975495

function memorySizeOf(obj) { var bytes = 0; function sizeOf(obj) { if(obj !== null && obj !== undefined) { switch(typeof obj) { case 'number': bytes += 8; break; case 'string': bytes += obj.length * 2; break; case 'boolean': bytes += 4; break; case 'object': var objClass = Object.prototype.toString.call(obj).slice(8, -1); if(objClass === 'Object' || objClass === 'Array') { for(var key in obj) { if(!obj.hasOwnProperty(key)) continue; sizeOf(obj[key]); } } else bytes += obj.toString().length * 2; break; } } return bytes; }; function formatByteSize(bytes) { if(bytes < 1024) return bytes + " bytes"; else if(bytes < 1048576) return(bytes / 1024).toFixed(3) + " KiB"; else if(bytes < 1073741824) return(bytes / 1048576).toFixed(3) + " MiB"; else return(bytes / 1073741824).toFixed(3) + " GiB"; }; return formatByteSize(sizeOf(obj)); }; var sizeOfStudentObject = memorySizeOf({Student: {firstName: 'firstName', lastName: 'lastName', marks: 10}}); console.log(sizeOfStudentObject);

你觉得怎么样?

在@Dan已经很紧凑的解决方案的基础上,这里有一个它的自包含函数版本。对于那些希望变量名尽可能紧凑而不考虑上下文的人来说,变量名被简化为单个字母。

const ns = {}; ns.sizeof = function(v) { let f = ns.sizeof, //this needs to match the name of the function itself, since arguments.callee.name is defunct o = { "undefined": () => 0, "boolean": () => 4, "number": () => 8, "string": i => 2 * i.length, "object": i => !i ? 0 : Object .keys(i) .reduce((t, k) => f(k) + f(i[k]) + t, 0) }; return o[typeof v](v); }; ns.undef; ns.bool = true; ns.num = 1; ns.string = "Hello"; ns.obj = { first_name: 'John', last_name: 'Doe', born: new Date(1980, 1, 1), favorite_foods: ['Pizza', 'Salad', 'Indian', 'Sushi'], can_juggle: true }; console.log(ns.sizeof(ns.undef)); console.log(ns.sizeof(ns.bool)); console.log(ns.sizeof(ns.num)); console.log(ns.sizeof(ns.string)); console.log(ns.sizeof(ns.obj)); console.log(ns.sizeof(ns.obj.favorite_foods));

有一个NPM模块来获取object sizeof,你可以用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));

我在原来的答案中重构了代码。我已经删除了递归和假定存在的开销。

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;
}