Srings & Arrays 在 JavaScript 中消耗多少内存?

How much memory do Srings & Arrays consume in JavaScript?

提问人:Vishal 提问时间:8/19/2023 最后编辑:Vishal 更新时间:8/19/2023 访问量:65

问:

我正在尝试理解字符串和数组使用的内存。根据这个有用的问题:JavaScript 字符串中有多少字节?

Blob是检查字符串字节大小的好方法:-> 字节new Blob(['a']).size1

但是字符串是用 JavaScript 编码的,它至少使用 .如何返回 1?UTF-162 bytesBlob

此外-----

const x = 200;
const y = 200;

const changes = []

for (let i=0;i<y;i++) {
    let subArr = []
    for (let j=0;j<x;j++) {
        subArr[j]= new Uint8Array(1)
    }
    changes[i]=subArr
}
console.log(new Blob(changes).size)

上面的数组使用 而不是 (Uint8Array(1) 的 200*200)。7980040000

  1. 为什么上面的数组消耗的 (79800) 是我预期的 (40000) 的两倍?另外,为什么第一个索引 (0) 被解释为 1 个字节,而后面的索引是 2 个字节?为什么?

'

for (let i=0;i<y;i++) {
   changes[i] = new Array(x).fill(new Uint8Array(1))
}
  1. 如果我使用上面的内容填充数组,它仍然会消耗 .为什么?正如评论中指出的那样,它是获得填充时间的同一对象。79800Uint8Arrayx
JavaScript UTF-16

评论

1赞 Heiko Theißen 8/19/2023
Blob以 UTF-8 格式存储字符串,如 其中 logs .for await (const chunk of new Blob(['aß']).stream()) console.log(chunk);Uint8Array(3) [ 97, 195, 159 ]
0赞 trincot 8/19/2023
标题的问题与问题的正文不同。Blob 和 String 是两个不同的东西。
0赞 Vishal 8/19/2023
@trincot 增加了清晰度。
0赞 trincot 8/19/2023
但是,您的问题正文是关于为什么在创建 blob 时获得某些输出......标题是关于 S(t) 环和数组的,而不是关于 Blob。此外,您应该只问 1 个问题,而不是 4 个问题。
0赞 CherryDT 8/19/2023
请注意,这将创建一个 single,并将对该同一数组的引用填充到新数组的所有元素中。它不会创建 s。new Array(x).fill(new Uint8Array(1))Uint8ArrayxxUint8Array

答:

3赞 Sergiu Paraschiv 8/19/2023 #1

Blob使用 UTF-8 表示字符串。 UTF-8 的最小字节大小为 1,字符可以使用单个字节以 UTF-8 表示。例如,一个两个字节的 UTF-8 字符( 返回 2,而像复杂表情符号 ( )这样更长的字符返回 4。'a''Ђ''😃'

关于 79800 与 40000 字节的示例:您没有构建一个 40000 字节的数组并将其传递给 。您正在构建一个字节数组数组。这些数组的“叶”节点确实是 40000 字节,但这不是你用来构建 Blob 的......Blob

文档有点模糊,但在您进行一些实验后很有帮助。

“blob 的内容由参数数组中给定的值的串联组成。”

值的串联。那是什么意思?串联是对数组的一种操作,术语主要用于表示“连接两个字符串”。好吧,让我们做一些实验:

await new Blob('a').text()使用 解析 ,解析为 ,,更接近您的示例,解析为 。哼。。。这是完全有道理的,因为也是。'a'await new Blob([new Uint8Array(1)]).text()'\x00'await new Blob([[new Uint8Array(1)]]).text()'0'new Uint8Array(1).toString()'0'

await new Blob([[new Uint8Array(1),new Uint8Array(1)]]).text()解析为 ,这也是有道理的,因为 is too。'0,0'[new Uint8Array(1),new Uint8Array(1)].toString()'0,0'

最后一个基本上是解释。当你把不是字符串的东西传递给它时,它会自动把它们变成“为你”的字符串Blob

而变成字符串的数组所占用的不仅仅是其元素的字符串表示,因为我们在它们之间也有逗号。

再次回到您的示例,您将 200 个实例的 200 个数组传递给 。每个“内部”数组都转换为一个字符串,这意味着它是 200 个字符加上 199 个字符。而 (200 + 199) * 200 是,你猜对了,79800!Uint8Array(1)Blob'0'','

这里的主要教训是:无论你传递到什么,首先都是“条纹”。Blob

评论

0赞 Vishal 8/19/2023
如果我的目标是减少内存消耗,我是否应该将所有字符串存储在 Blob 中?或者有比 Blob 更好的方法吗?
1赞 Pointy 8/19/2023
@Vishal这将使代码变得非常繁琐。在任何给定时间,内存中真正需要多少文本?您的应用是什么,为什么会担心?
0赞 Sergiu Paraschiv 8/19/2023
你只需要传递这些数据吗?您需要进行转换吗?
0赞 Vishal 8/19/2023
@Pointy小型硬件,内存有限,只有几 MB 内存
0赞 Vishal 8/19/2023
@SergiuParaschiv 是的,数据将在客户端、服务器和数据库之间来回传递。没有转换,也没有超过 1 字节的字符。