我想知道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),那就太棒了。

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


当前回答

我有问题与上面的答案与ArrayBuffer。 在检查文档之后,我发现ArrayBuffer有一个byteLength属性,它告诉我我需要什么,因此:

函数sizeOf(数据) { If (typeof(data) === 'object') { if (ArrayBuffer的数据实例) { 返回data.byteLength; } //其他对象在这里 } //非对象情况 } console.log (sizeOf(新ArrayBuffer (15)));/ / 15

参考:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/byteLength

其他回答

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

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

非常感谢所有为此编写代码的人!

我只是想补充一点,我一直在寻找完全相同的东西,但在我的情况下,它是为了管理已处理对象的缓存,以避免不得不重新解析和处理来自ajax调用的对象,这些调用可能已被浏览器缓存,也可能未被浏览器缓存。这对于需要大量处理的对象特别有用,通常不是JSON格式的任何东西,但将这些东西缓存在大型项目或长时间运行的应用程序/扩展中成本非常高。

不管怎样,我用它来做一些事情,比如:

var myCache = {
    cache: {},
    order: [],
    size: 0,
    maxSize: 2 * 1024 * 1024, // 2mb

    add: function(key, object) {
        // Otherwise add new object
        var size = this.getObjectSize(object);
        if (size > this.maxSize) return; // Can't store this object

        var total = this.size + size;

        // Check for existing entry, as replacing it will free up space
        if (typeof(this.cache[key]) !== 'undefined') {
            for (var i = 0; i < this.order.length; ++i) {
                var entry = this.order[i];
                if (entry.key === key) {
                    total -= entry.size;
                    this.order.splice(i, 1);
                    break;
                }
            }
        }

        while (total > this.maxSize) {
            var entry = this.order.shift();
            delete this.cache[entry.key];
            total -= entry.size;
        }

        this.cache[key] = object;
        this.order.push({ size: size, key: key });
        this.size = total;
    },

    get: function(key) {
        var value = this.cache[key];
        if (typeof(value) !== 'undefined') { // Return this key for longer
            for (var i = 0; i < this.order.length; ++i) {
                var entry = this.order[i];
                if (entry.key === key) {
                    this.order.splice(i, 1);
                    this.order.push(entry);
                    break;
                }
            }
        }
        return value;
    },

    getObjectSize: function(object) {
        // Code from above estimating functions
    },
};

这是一个简单的例子,可能会有一些错误,但它给出了一个想法,因为你可以使用它来保持静态对象(内容不会改变)与某种程度的智能。这可以大大减少任何昂贵的处理要求,对象必须在第一时间生产。

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

但是,如果你正在使用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 );
}

我知道这绝对不是正确的方法,但它在过去几次帮助我得到了大致的对象文件大小:

将对象/响应写入控制台或新选项卡,将结果复制到新的记事本文件,保存它,并检查文件大小。记事本文件本身只有几个字节,因此您将获得相当精确的目标文件大小。

谷歌Chrome堆分析器允许您检查对象内存使用。

您需要能够在跟踪中定位对象,这可能很棘手。如果您将对象固定到Window全局,则很容易从“Containment”列表模式中找到它。

在附件的截图中,我在窗口上创建了一个名为“testObj”的对象。然后我定位在分析器(在做了一个记录后),它显示了对象的完整大小和它在“保留大小”下的所有内容。

关于内存故障的更多细节。

在上面的屏幕截图中,对象显示的保留大小为60。这里的单位应该是字节。