8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

常见的 JavaScript 实现是否使用字符串驻留?

veritas 2月前

64 0

常见的 JavaScript 引擎(例如 V8 和 WebKit 的 JavaScriptCore)是否对 JavaScript 字符串使用字符串驻留?或者它们实际上在内存中保留了相同字符串的多个实例?

常见的 JavaScript 引擎(例如 V8 和 WebKit 的 JavaScriptCore)是否对 JavaScript 字符串使用 字符串驻留 ?或者它们实际上在内存中保留了相同字符串的多个实例?

帖子版权声明 1、本帖标题:常见的 JavaScript 实现是否使用字符串驻留?
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由veritas在本站《string》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 是的。一般来说,JS 源代码中的任何文字字符串、标识符或其他常量字符串都会被驻留。但是,实现细节(例如,究竟驻留什么)以及驻留发生的时间各不相同。

    请注意,字符串值与字符串对象并不相同,字符串对象不会被驻留,因为那从根本上来说是不正确的行为。

  • @FelipeSabino 在主要引擎上工作和加入 ecmascript 委员会算吗?;) 不过更严肃一点,你可以在线查看 JavaScriptCore、SpiderMonkey、V8 等的源代码。

  • 当然我可以查看任何开源代码并亲自检查,但 SO 存在的原因之一就是为了避免这种麻烦,哈哈。这不是怀疑你的知识的问题,只是关心如何帮助开发人员进行研究。看来你是一个对这个主题很了解的人,而且还有更多有力的参考资料可以帮助我更多地了解这个主题。举个例子,你说“一般来说字符串是被保留的”,那么在什么情况下它们不是呢?等等……

  • @FelipeSabino 驻留逻辑(至少在 JSC 中)分布在多个领域。但基本模型与 Java 类似——常量字符串会自动驻留,而字符串连接的结果等则不会。在 Java 中,您可以明确强制驻留,但在 JS 中不存在。

  • @olliej 您能否看看这里 - 这里有一场激烈的辩论 .com/questions/26549715/… 也在这里 .com/questions/26532550/…。谢谢!非常感谢您的帮助 :)

  • http://jsperf.com/strinterning

    在 Chrome 中是,但在 Aurora 15 和 FF 13 中不是!在 Firefox 中比较两个字符串比比较两个指针慢 85%。然而在 Chrome 中速度相同,这表明它正在比较两个指针。

    也许 Mozilla 的 JS 引擎团队应该检查他们的代码……

  • 如果您认为这很糟糕,那么 IE9 在将字符串变量与其自身进行比较时甚至不会进行指针比较。(相关 JSPerfs。)

  • 简短的回答: 有时是,有时不是。

    我也偶然发现了同样的问题,并对其进行了一番研究。似乎实习通常是针对以相同方式生成的字符串文字进行的(例如,始终将相同的字符串分配给同一循环中的变量),但我还能够创建一个示例,该示例导致使用两个不同的引用创建两个相同的字符串:

    Chrome dev tools heap snapshot showing pairs of identical string values with different reference IDs

    如您所见,每个字符串存储两次,具有不同的引用。

    这是我用来生成重复字符串的代码:

    const a = [];
    const b = [];
    
    for(let j  =1; j<= 100;++j){
        for(let i = 1; i <= 10000; ++i) a[i] = 'player 1 got 5 points from player 2' + i;
        for(let i = 1; i <= 10000; ++i) b[i] = 'player 1 got 5 points from player 2' + i;
    }
    

    看起来字符串驻留是针对字符串文字进行的,而不是针对连接的字符串值进行的,但正如上面看到的,每个连接的字符串只出现两次,而不是 100x2 = 200 次,因此在外层循环中创建的连接字符串仍然会进行字符串驻留。

  • 这是什么控制台?我无法让左侧的箭头出现在字符串上,或者更奇怪的是,在 opera/chrome/firefox 上,右侧的灰色引用无法出现

  • @XCS 我不认为这是正确的:“对于在外部循环中创建的连接字符串,仍然进行了字符串驻留”。您没有维护对在外部循环的早期迭代中创建的字符串的引用(每次迭代您都会覆盖 a 和 b 的每个元素),但“只有可访问的对象才会包含在快照中。”如果您维护对早期连接字符串的引用,那么您确实会获得每个字符串的 200 个副本。

  • @XCS 我不知道,不幸的是,这就是我到处搜索并发现这个问题的原因!:) 我唯一确定的是,您的测试用例并没有说明连接字符串被驻留的情况,而是说明了堆快照不包含无法访问的对象。但是,可能还存在连接字符串被驻留的其他情况,我不知道如何找到这种情况或证明它们不存在。

返回
作者最近主题: