英文:
Memory consumption of storing reference to HTML Element vs Other options
问题
以下是翻译好的部分:
"在存储示例中的内存消耗方面,存储对HTML元素的引用与存储字符串或数字之间的差异有多大?
const el = document.getElementById("myEl");
const myCache = new Set()
// 存储对元素的引用
myCache.add(el);
// 或者存储随机字符串
myCache.add("someStr");
// 或者存储随机数字
myCache.add(0);
这在内存中的表现如何,哪一个是最节省内存的解决方案。"
英文:
How big is the difference in memory consumption when storing for Example a reference to an HTML Element in memory vs a String or a Number?
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);
How does this look in the Memory, what is the most memory friendly solution out of them.
答案1
得分: 3
以下是翻译的内容:
首先让我们从 Chrome 堆转储中查看内存消耗。
一组包含 1509 个字符串,每个字符串有 144 个字符,消耗 231776 字节:
一组包含 1509 个字符串,每个字符串有 72 个字符,消耗 111056 字节:
一组包含 1509 个字符串,每个字符串有 36 个字符,消耗 50696 字节:
一组包含 1509 个元素,消耗 20516 字节:
一组包含 1509 个数字 也消耗 20516 字节:
因此,字符串集的大小因每个项的长度而异,但元素和数字的内存大小保持一致。
现在来回答您的问题。最节省内存的方法可能会根据用例而异。
一组元素 实际上会存储元素引用。JS 中对象引用的大小为 8 字节。
一组元素引用可能看起来是一种解决方案,因为该集仅持有对元素的引用,元素的内存已分配,因为它是 DOM 的一部分。因此,没有什么真正的增加。
但是,使用元素引用创建集的一个问题是,如果在从 DOM 中删除元素后不删除元素引用,由于集中保留了元素引用,它将继续消耗为已删除元素分配的内存。如果页面上频繁添加/删除元素,并且集保留所有元素引用,在这种情况下可能会导致内存泄漏。在这种情况下,我们必须从集中删除已删除的元素引用。Element.isConnected
是一个布尔属性,如果元素仍连接到 DOM,则返回 true,如果元素从 DOM 中删除,则返回 false。
一组字符串,字符串将存储在堆中,而集将保持它们的引用。最终,这种方法中的内存消耗将取决于您添加的字符串的大小。
现在,对于 一组数字,范围从 -2¹⁷⁹ 到 2¹⁷⁹-1 的小整数将直接存储在 Set
中,消耗 8 字节,不需要额外的堆分配。超出范围的数字将存储在堆中,而集将保持对它们的引用,每个数字将在堆中占用 12 字节。因此,在这里,您也基本上获得了一种一致的大小。
根据不同数据类型相同大小的集的结论
Set
只存储您添加到其中的项的引用。因此,差异主要是由堆中项的大小引起的。- 如果您的字符串长度较小,可以选择它。
- 如果您的用例适用于元素方法并且正确处理内存泄漏,您可以选择元素集方法。
- 在大多数情况下,一组数字可能是一个不错的选择。
英文:
Let's see the memory consumption from chrome heap dump first.
A Set of 1509 strings each of 144 characters consumes 231776 bytes:
A Set of 1509 strings each of 72 characters consumes 111056 bytes:
A Set of 1509 strings each of 36 characters consumes 50696 bytes:
A Set of 1509 elements consumes 20516 bytes:
A Set of 1509 numbers also consumes 20516 bytes:
So, size of the Set of string varies with the size of each item length but memory size is consistent for elements and number.
Now coming to answering your question. The most memory efficient approach may vary depending on the use-case.
A set of element will actually store the element references. The size for object reference in JS is 8bytes.
A set of element reference may looks to be a solution which consumes consistent memory as the set is only holding the references to the element and the memory for the element is already allocated as it is part of the DOM. So nothing really increasing as such.
But, one problem with creating a set with element references is, if we do not remove the element reference after the element is removed from the DOM, due to the element reference hold in the set, it will keep consuming the memory allocated for that removed element. If on the page the add / remove element happens very frequently and the set is holding all element references, it can cause memory leak. In such situation we must be removing the removed element references from the set. Element.isConnected
is a boolean property gives true if the element still attached to the DOM and false if the element is removed from the DOM.
A set of strings, the strings will be stored in heap and the set will hold their reference. Ultimately, the memory consumption in this approach will depend on the size of the strings you are adding.
Now for a set of numbers, Small integers ranging from -2³¹ to 2³¹-1 will be directly stored in the Set
consuming 8bytes, no extra heap allocation will be required. Numbers exceeding the range will be stored in the heap and the set will hold their references for that each number will consume 12bytes in heap. So, here also you get mostly a consistent size.
Conclusion Based on same size set for different data types
- A
Set
just stores the reference of the items you are adding into it. So the difference is mainly due to the size of the item in heap. - If you have strings with small length, you can go with it.
- If your use-case suites the element approach and handle the memory leak properly you may choose the set of elements approach.
- A set of number can be a decent choice in most cases.
答案2
得分: 1
对象引用、字符串或数字占用多少内存空间是特定于JavaScript引擎的实现细节。但如果我们以V8(用于Chromium和Node.js的引擎)为例:
一个指向对象的引用,就像你的el变量中所包含的,占用4个字节。
参见:https://v8.dev/blog/pointer-compression
但一般来说:要存储对象引用所需的是内存中的地址。
由7个字符组成的字符串占用20个字节。
参见:这个公式:12 + 4 * Math.ceil(n/4),在这里找到 https://stackoverflow.com/questions/68789144/how-much-memory-do-v8-take-to-store-a-string
据我所知,数字存储为64位浮点数(8字节)。
因此,字符串将占用最多的内存(20字节),数字(8字节),而对象引用仅占用4字节。使用对象引用,它们还能简化生活(除非你需要序列化)。
英文:
How much space an object reference, as well as a string or a number, takes is implementation specific to the JavaScript engine. But if we go from V8 (the enginge used in Chromium and Node.js):
A reference to an object, which is what you have in your el variable, takes 4 bytes.
See: https://v8.dev/blog/pointer-compression
But in general: What needs to be stored for an object reference is an address in memory.
A string consisting of 7 characters would take 20 bytes.
See: This formula: 12 + 4 * Math.ceil(n/4) found here https://stackoverflow.com/questions/68789144/how-much-memory-do-v8-take-to-store-a-string
And as far I can tell a Number is stored as a 64-bit float (8 bytes).
So the string will consume the most memory (20 bytes), the number (8 bytes) and an object reference just 4 bytes. Go with object references, they also make life easy (unless you need serialization).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论