存储对 HTML 元素的引用与其他选项的内存消耗

问题描述 投票:0回答:2

在内存中存储对 HTML 元素的引用与字符串或数字时,内存消耗的差异有多大?

const el = document.getElementById("myEl");

const myCache = new Set()

// store reference to element
myCache.add(el);

// VS store a random string
myCache.add("someStr");

// VS store a random number
myCache.add(0);

这在内存中看起来如何,其中对内存最友好的解决方案是什么。

javascript html v8
2个回答
2
投票

让我们先看看 chrome heap dump 的内存消耗。

A Set 1509 个字符串,每个字符串 144 个字符 消耗 231776 字节

一组 1509 个字符串,每个 72 个字符 消耗 111056 字节

一组 1509 个字符串,每个 36 个字符 消耗 50696 字节

一组1509个元素消耗20516字节

一组1509个数字也消耗20516字节

因此,字符串集合的大小随每个项目长度的大小而变化,但内存大小对于元素和数量是一致的。

现在来回答你的问题。内存效率最高的方法可能因用例而异。

一组元素实际上将存储元素引用。 JS 中对象引用的大小是 8bytes。

一组元素引用可能看起来是一个消耗一致内存的解决方案,因为该集合只保存对元素的引用,并且元素的内存已经分配,因为它是 DOM 的一部分。所以没有什么真正增加。

但是,使用元素引用创建集合的一个问题是,如果我们在从 DOM 中删除元素后不删除元素引用,由于元素引用保留在集合中,它将继续消耗为此分配的内存删除的元素。如果在页面上添加/删除元素非常频繁,并且集合持有所有元素引用,则可能导致内存泄漏。在这种情况下,我们必须从集合中删除已删除的元素引用。

Element.isConnected
是一个布尔属性,如果元素仍然附加到 DOM,则为 true;如果元素已从 DOM 中删除,则为 false。

一组字符串,字符串将作为值存储在集合中,因此如果您已经在其他地方保存值,它将被复制[这就是我的想法,有可能针对浏览器进行特定优化]。集合的大小将取决于您添加的字符串的大小。

现在对于一组数字,数字也将存储为值。 JS 中的一个数字占用 8 个字节。所以在这里你也可以获得一致的尺寸。

Conclusion Based on same size set for different data types

  • 如果您的琴弦长度较短,您可以搭配它。
  • 如果您的用例适合元素方法并正确处理内存泄漏,您可以选择元素集方法。
  • 在大多数情况下,一组数字是不错的选择。

1
投票

对象引用以及字符串或数字占用多少空间是特定于 JavaScript 引擎的实现。但是如果我们从 V8(Chromium 和 Node.js 中使用的引擎)开始:

对对象的引用,即您在 el 变量中的内容,占用 8 个字节。

参见:https://www.mattzeunert.com/2017/03/29/v8-object-size.html

在这种情况下它是 DOM 元素,也许 V8 和 Blink 之间的绑定增加了一些东西?不确定。

但总的来说:对象引用需要存储的是内存中的地址。

由 7 个字符组成的字符串将占用 20 个字节。

参见:这个公式:12 + 4 * Math.ceil(n/4) 在这里找到v8 需要多少内存来存储一个字符串?

据我所知,数字存储为 64 位浮点数(8 字节)。

所以我从上面的事实猜测是字符串会消耗最多的内存,而数字和对象引用在内存消耗方面相当相等。但这是一个猜测,因为我不知道是否有任何内存压缩算法位于所有这些之上,在这种情况下,可能会压缩几个相同或相似的数字或对同一对象的多个引用。

© www.soinside.com 2019 - 2024. All rights reserved.