【问题标题】:how much memory do v8 take to store a string?v8 需要多少内存来存储一个字符串?
【发布时间】:2021-08-15 06:15:00
【问题描述】:

我正在尝试计算 v8 中字符串的内存使用情况,我知道单个字符需要 2 个字节。但是当我在 devtools 中检查浅层大小和保留大小时,我对结果感到困惑:

function Student() {
    this.name = 'lll';
}

var a = new Student();

var b = new String("ccccc");

浅层大小和保留大小都是 16 字节。为什么?

正如我想象的那样,浅层大小和保留大小将相等,并且值将是 6 个字节。如果我将字符串从“llll”更改为“llll”,该值将增加 2 个字节。但它保持与以下相同:

谁能给我解释一下?

【问题讨论】:

标签: javascript memory v8


【解决方案1】:

(这里是 V8 开发人员。)
前面的一般注意事项:字符串在 Web 上非常常见,因此 JavaScript 引擎竭尽全力为您可以用字符串做的许多不同事情实现许多不同的优化,因此,现代 JS 引擎中的字符串处理系统倾向于要很复杂。有了这些,我们可以在这里专注于“简单”的字符串。

单个字符需要 2 个字节

还有一点:V8 在内部区分一字节和二字节字符串。当给定字符串中的所有字符都可以只用一个字节表示时,(通常)这就是 V8 会做的事情。

浅层大小和保留大小都是 16 字节。为什么?

评论者已经发布了一个链接来描述“浅”和“保留”大小之间的差异,所以我不会深入讨论。对于简单的字符串,它确实总是相同的值。

堆上的所有对象都以一个形状描述符开始,它采用一个指针大小(现在通常是 4 个字节,这要归功于 64 位平台上的“指针压缩”)。

字符串在它们的对象头中还有另外两个 4 字节的字段:字符串的散列(这是非常需要的,因此为了避免一直重新计算它,它被缓存在那里),以及字符串的长度。

之后,它们存储实际字符。任何堆对象的大小必须是指针大小的倍数,即 4 的倍数,因此字符串的大小向上舍入;最后几个字节可能未使用。

所以,综上所述,n ASCII 字符的简单字符串的大小为:

12 + 4 * Math.ceil(n/4)

(这可能会随着时间的推移而改变,如果在构建时关闭指针压缩会有所不同,字符串中有两个字节字符时会有所不同,字符串中会有所不同“sliced”或“cons”字符串,当字符串与 Blink 共享时会有所不同,我可能忘记了某些情况下它也会有所不同。)

如果您稍微扩展一下实验,您会看到:
"" 占用 12 个字节
"1""1234" 占用 16 个字节
"12345""12345678"占用 20 个字节
"123456789" 占用 24 个字节,以此类推。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-29
    • 1970-01-01
    • 2014-05-11
    相关资源
    最近更新 更多