如何获取 JavaScript 对象的大小?

IT技术 javascript memory object sizeof
2021-01-14 11:47:10

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

取以下函数:

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

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

现在我实例化student

var stud = new Student();

这样我就可以做类似的事情

stud.firstName = "new Firstname";

alert(stud.firstName);

stud.marks.maxMarks = 200;

等等。

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

我如何找出stud对象占用了多少内存类似于sizeof()JavaScript 中的 a ?如果我能在像sizeof(stud).

我已经在互联网上搜索了几个月 - 找不到它(在几个论坛中询问 - 没有回复)。

6个回答

我已经在我的原始答案中重新分解了代码我已经删除了递归并删除了假设的存在开销。

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;
}
您可能还想考虑对象键
2021-03-14 11:47:10
任何为了 false/true 的目的来到这里寻找最小类型的人,它似乎是 undefined/null。
2021-03-23 11:47:10
"よんもじ".length 在 Javascript 中是 4,​​但是当您的代码返回它时,您确定它是 8 个字节吗?
2021-04-02 11:47:10
此函数不计算隐藏在闭包中的引用。例如var a={n:1}; var b={a:function(){return a}}; roughSizeOfObject(b)——这里b持有对 的引用a,但roughSizeOfObject()返回0
2021-04-09 11:47:10
是的。JavaScript 中的字符根据 ECMA-262 第 3 版规范存储 - bclary.com/2004/11/07/#a-4.3.16
2021-04-10 11:47:10

Google Chrome Heap Profiler 允许您检查对象内存使用情况。

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

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

有关内存故障的更多详细信息

Chrome 分析器

在上面的截图中,对象显示保留大小为 60。我相信这里的单位是字节。

Shallow sizeof{ a:"55c2067aee27593c03b7acbe", b:"55c2067aee27593c03b7acbe", c:null, d:undefined }{ c:null, d:undefined }objects似乎都是 40 可以吗?
2021-03-29 11:47:10
@Johnride 提到的比较现在是顶部的下拉菜单。
2021-03-30 11:47:10
您也可以从 node 使用 Google Chrome Heap Profiler。如果您有 node v8 或更高版本node --inspect,请在 Chrome 中启动它并在about:inspectURL 栏中输入并查找打开节点检查器。在节点 CLI 中创建您的对象,然后拍摄堆快照。
2021-04-02 11:47:10
这个回答解决了我的问题一起:developers.google.com/chrome-developer-tools/docs/...快速提示:快速拍摄堆快照,运行您怀疑正在泄漏的任务,拍摄新的快速堆快照并选择comparison底部视图。很明显在两个快照之间创建了哪些对象。
2021-04-03 11:47:10

我只是写这个来解决一个类似的(ish)问题。它并不完全符合您的要求,即它没有考虑解释器如何存储对象。

但是,如果您使用的是 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 );
}

有时我使用它来标记可能从服务器发送到客户端的非常大的对象。它不代表内存占用。它只是让您大致了解发送或存储它的成本。

另请注意,它很慢,仅限开发人员。但是为了用一行代码得到一个大概的答案,它对我很有用。

roughObjSize = JSON.stringify(bigObject).length;
根据我的测试,此方法比 object-sizeof 情况快得多,因为它没有来自 lodash 的缓慢 _.isObject() 调用。此外,返回的大小与粗略估计相当。要点gist.github.com/owenallenaz/ff77fc98081708146495
2021-03-17 11:47:10
如果 1) 你只需要一个大概的估计 2) 你知道你没有任何循环引用 3) 你可以省略大值并单独处理它们,这非常好。在我的情况下,所有这些都是正确的,所以效果很好,我在一个地方只有一根大绳子,我可以测量长度。
2021-03-20 11:47:10
不能与圆形结构一起使用VM1409:1 Uncaught TypeError: Converting circular structure to JSON:(虽然仍然有用
2021-03-25 11:47:10
2021-03-29 11:47:10
这不是以字节为单位的二进制大小,而是易于使用以获得近似大小
2021-04-04 11:47:10

这是该问题的一个稍微紧凑的解决方案:

const typeSizes = {
  "undefined": () => 0,
  "boolean": () => 4,
  "number": () => 8,
  "string": item => 2 * item.length,
  "object": item => !item ? 0 : Object
    .keys(item)
    .reduce((total, key) => sizeOf(key) + sizeOf(item[key]) + total, 0)
};

const sizeOf = value => typeSizes[typeof value](value);
@vincent-thorpe 以字节为单位。
2021-03-11 11:47:10
所以这是以 KB 为单位的大小?还是位?
2021-03-28 11:47:10
@JosuGoñi,他们不计算对象本身需要多少,只计算它的value。所有对象都占用更多空间,而不仅仅是它们的值,否则typeof ...将无法工作。
2021-04-03 11:47:10
不错的脚本,但需要修改循环引用。
2021-04-04 11:47:10
我刚刚在一个节点进程中的大量数据上测试了你的算法,它报告了 13GB,但节点消耗了 22GB,知道差异来自哪里吗?记忆中没有更多的东西了。
2021-04-05 11:47:10