Chrome内存快照中的保留大小-究竟保留了什么? [英] Retained Size in Chrome memory snapshot - what exactly is being retained?

查看:165
本文介绍了Chrome内存快照中的保留大小-究竟保留了什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

浅大小为24字节,这与我们存储3 x 8字节双精度数的事实完全匹配.额外"大小为36字节,它允许存储9 x 4字节指针(假设指针压缩处于打开状态).如果我们添加三个额外的属性,则额外的大小将为72(!)字节,因此它取决于属性的数量.那里存储了什么?是否有可能避免如此大的内存开销?

解决方案

V8开发人员在这里.

浅尺寸是对象本身,由标准对象标头(3个指针)和3个对象内属性组成,它们又是指针.那是6个(压缩的)指针,每个指针4个字节= 24个字节.

其他保留大小是三个属性的存储空间.它们每个都是一个"HeapNumber",由一个4字节的映射指针和一个8字节的有效负载组成.因此,这是3个属性乘以12字节= 36字节.(掌握了这些知识后,再加上三个属性(大概也是数字)就翻倍为72,也就不足为奇了.

加起来,每个对象总共占用24 + 36 = 60字节.

地图和原型不计入每个对象的保留大小,因为它们被所有对象共享,因此释放一个对象也将不允许它们也被释放.

一种节省内存(如果您认为很重要)的想法是转置"数据组织:您可以让1个对象包含3个数组(每个数组包含100,000个数字,而不是每个数组包含3个数字的100,000个对象)..根据您的用例,这可能是可行的方法,也可能不是一种可行的方法:如果三倍的数字来回频繁,那么将它们存储在一个巨大的数组中将是不愉快的;相反,如果这是一个静态数据集,那么这两个模型的可用性可能相当相等.如果这样做,将避免重复的每个对象的开销;另外,数组可以内联存储双精度数字(只要整个数组仅包含 个数字),那么您就可以存储相同的300K数字,而总内存却只有2.4MB.

如果尝试用许多小的TypedArray替换3属性对象,则会发现内存使用量显着增加,因为TypedArrays的单对象开销比简单对象大得多.他们的目标是拥有一些大型阵列,而不是许多小型阵列.

Chrome docs says that retained size is "the size of memory that is freed once the object itself is deleted along with its dependent objects that were made unreachable from GC roots" which is fair enough. However, even for simple objects, retained size is often 3x of shallow size. I understand that V8 need to store reference to hidden shape, probably some data for GC and so on, but sometimes objects have hundreds of extra "retained" bytes, which seems to be a problem when you need to have millions of such objects. Let's take a look at a simple example:

class TestObject {
    constructor( x, y, z ) {
        this.x = x;
        this.y = y;
        this.z = z;
    }
}

window.arr = [];
for ( let i = 0; i < 100000; i++ ) {
    window.arr.push( new TestObject( Math.random(), Math.random(), Math.random() ) );
}

Here's the memory snapshot:

Shallow size is 24 bytes, which is perfectly matches with the fact that we're storing 3 x 8-byte doubles. "Extra" size is 36 bytes, which allows to store 9 x 4-byte pointers (assuming that pointer compression is on). If we add three extra properties, extra size will be 72 (!) bytes, so it depends on number of properties. What is being stored there? Is it possible to avoid such massive memory overhead?

解决方案

V8 developer here.

Shallow size is the object itself, consisting of the standard object header (3 pointers) and 3 in-object properties, which are again pointers. That's 6 (compressed) pointers of 4 bytes each = 24 bytes.

Additional retained size is the storage for the three properties. Each of them is a "HeapNumber", consisting of a 4-byte map pointer plus an 8-byte payload. So that's 3 properties times 12 bytes = 36 bytes. (Armed with this knowledge, it shouldn't be surprising that with another three properties, which presumably are also numbers, this doubles to 72.)

Added up, each object occupies a total of 24+36 = 60 bytes.

Map and prototype don't count for each object's retained size because they are shared by all objects, so freeing one object wouldn't allow them to be freed as well.

One idea to save memory (if you feel that it is important) is to "transpose" your data organization: instead of 1 array containing 100,000 objects with 3 numbers each, you could have 1 object containing 3 arrays with 100,000 numbers each. Depending on your use case, this may or may not be a feasible approach: if the triples of numbers come and go a lot, then storing them in a single huge array would be unpleasant; whereas if it's a static data set, then both models might be fairly equivalent in usability. If you did this, you'd avoid the repeated per-object overhead; additionally arrays can store double numbers inline (as long as the entire array contains only numbers), so you'd be able to store the same 300K numbers with only 2.4MB total memory consumption.

If you try replacing the 3-property objects with many small TypedArrays, you'll see a significant increase in memory usage, because TypedArrays have much bigger per-object overhead than simple objects. They are geared towards having a few large arrays, not many small ones.

这篇关于Chrome内存快照中的保留大小-究竟保留了什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆