有谁对如何使用 Chrome(V8) 在 Javascript 中确定字符串的堆大小有很好的理解/解释吗?
我在堆转储中看到的一些示例:
1) 相同的 2 个字符串(即“dt”)的多个副本,但具有不同的值@
对象 ID 全部指定为 OneByteStrings。 heapdump 表示每个副本的浅层保留大小为 32 字节。目前尚不清楚两字节字符串如何保留 32 的大小以及为什么这些字符串似乎没有被保留。
2) 长对象路径字符串,长度为 78 个字符。所有字符在 utf8 中都是一个字节。它被归类为InternalizedString。它的保留大小为 184 字节。即使使用 2 字节字符编码,仍然无法解释剩余的 28 字节。为什么这些路径字符串占用这么多空间?我可以想象另外 4 个字节(可能是 8 个)用于地址,另外 4 个字节用于存储字符串长度,但即使使用 2 字节字符编码,仍然剩下 16 个字节。
在内部,V8 有许多不同的字符串表示形式:
- SeqOneByteString:最简单,包含一些头字段,然后是字符串的字节(不是UTF-8编码的,只能包含前256个unicode代码点中的字符)
- SeqTwoByteString:相同,但每个字符使用两个字节(使用代理对来表示无法用两个字节表示的 unicode 字符)。
- SlicedString:其他字符串的子字符串。包含指向“父”字符串的指针以及偏移量和长度。
- ConsString:两个字符串相加的结果(如果超过一定大小)。包含指向两个字符串的指针(它们本身可以是这些类型的字符串中的任何一种)。
- ExternalString:用于从V8外部传入的字符串。
“Internalized”只是一个标志,实际的字符串表示形式可以是上述任何一种。
所有这些都有一个共同的父类 String,其父类是 Name,其父类是 HeapObject(这是在 V8 堆上分配的对象的 V8 类层次结构的根)。
- HeapObject 有一个字段:指向其 Map 的指针(对此有一个很好的解释)here http://jayconrod.com/posts/52/a-tour-of-v8-object-representation).
- 名称添加了一个附加字段:哈希值。
- String 添加了另一个字段:长度。
在 32 位系统上,每个字节都是 4 个字节。在64位系统上,每个是8字节。
如果您使用的是 64 位系统,则 SeqOneByteString 的最小大小将为 32 字节:上述标头字段为 24 字节,加上至少 1 个字符串数据字节,四舍五入为 8 的倍数。
关于你的第二个问题,很难说清楚到底发生了什么。可能是该字符串使用 2 字节表示形式,并且其标头字段将大小推高到超出您的预期,或者可能是它是 ConsString 或 SlicedString(其保留的大小将包括它指向的字符串)到)。
V8 大多数时候不会内化字符串 - 它会内化在解析过程中找到的字符串常量和标识符名称,以及用作对象属性键的字符串,以及可能的其他一些情况。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)