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

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


当前回答

接受的答案不适用于Map, Set, WeakMap和其他可迭代对象。(在其他回答中提到的包object-sizeof也有同样的问题)。

这是我的解决方案

export function roughSizeOfObject(object) {
  const objectList = [];
  const stack = [object];
  const bytes = [0];
  while (stack.length) {
    const value = stack.pop();
    if (value == null) bytes[0] += 4;
    else if (typeof value === 'boolean') bytes[0] += 4;
    else if (typeof value === 'string') bytes[0] += value.length * 2;
    else if (typeof value === 'number') bytes[0] += 8;
    else if (typeof value === 'object' && objectList.indexOf(value) === -1) {
      objectList.push(value);
      if (typeof value.byteLength === 'number') bytes[0] += value.byteLength;
      else if (value[Symbol.iterator]) {
        // eslint-disable-next-line no-restricted-syntax
        for (const v of value) stack.push(v);
      } else {
        Object.keys(value).forEach(k => { 
           bytes[0] += k.length * 2; stack.push(value[k]);
        });
      }
    }
  }
  return bytes[0];
}

它还包括其他一些小的改进:计算键存储和与ArrayBuffer一起工作。

其他回答

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

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

有时我用它来标记非常大的对象,这些对象可能会从服务器发送到客户端。它不代表内存占用。它只会让你得到大约发送或存储它的成本。

还请注意,它很慢,仅用于开发。但是用一行代码就能得到大概的答案,这对我来说很有用。

roughObjSize = JSON.stringify(bigObject).length;

有同样的问题。我在谷歌上搜索,我想与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);

你觉得怎么样?

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

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

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

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

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

接受的答案不适用于Map, Set, WeakMap和其他可迭代对象。(在其他回答中提到的包object-sizeof也有同样的问题)。

这是我的解决方案

export function roughSizeOfObject(object) {
  const objectList = [];
  const stack = [object];
  const bytes = [0];
  while (stack.length) {
    const value = stack.pop();
    if (value == null) bytes[0] += 4;
    else if (typeof value === 'boolean') bytes[0] += 4;
    else if (typeof value === 'string') bytes[0] += value.length * 2;
    else if (typeof value === 'number') bytes[0] += 8;
    else if (typeof value === 'object' && objectList.indexOf(value) === -1) {
      objectList.push(value);
      if (typeof value.byteLength === 'number') bytes[0] += value.byteLength;
      else if (value[Symbol.iterator]) {
        // eslint-disable-next-line no-restricted-syntax
        for (const v of value) stack.push(v);
      } else {
        Object.keys(value).forEach(k => { 
           bytes[0] += k.length * 2; stack.push(value[k]);
        });
      }
    }
  }
  return bytes[0];
}

它还包括其他一些小的改进:计算键存储和与ArrayBuffer一起工作。