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

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


当前回答

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

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

roughObjSize = JSON.stringify(bigObject).length;

其他回答

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

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

roughObjSize = JSON.stringify(bigObject).length;

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

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

有一个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));

我使用Chrome开发工具的Timeline选项卡,实例化越来越多的对象,并得到像这样的良好估计。你可以像下面这样使用html作为样板,并修改它以更好地模拟对象的特征(属性的数量和类型等)。您可能希望在运行之前和之后单击开发工具选项卡底部的“垃圾位”图标。

<html>
<script>
var size = 1000*100
window.onload = function() {
  document.getElementById("quantifier").value = size
}

function scaffold()
{
  console.log("processing Scaffold...");
  a = new Array
}

function start()
{
  size = document.getElementById("quantifier").value
  console.log("Starting... quantifier is " + size);
  console.log("starting test")
  for (i=0; i<size; i++){
    a[i]={"some" : "thing"}
  }
  console.log("done...")
}

function tearDown()
{
  console.log("processing teardown");
  a.length=0
}

</script>
<body>
    <span style="color:green;">Quantifier:</span>
    <input id="quantifier" style="color:green;" type="text"></input>
    <button onclick="scaffold()">Scaffold</button>
    <button onclick="start()">Start</button>
    <button onclick="tearDown()">Clean</button>
    <br/>
</body>
</html>

在我的Chromium上,实例化200万个对象,每个对象只有一个属性(如上面的代码所示)导致每个对象的粗略计算为50个字节。更改代码为每个对象创建一个随机字符串会为每个对象增加大约30个字节,等等。 希望这能有所帮助。

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

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

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

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

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