【问题标题】:Ruby symbols are not garbage collected!? Then, isn't it better to use a String?Ruby 符号不是垃圾收集的!?那么,使用String不是更好吗?
【发布时间】:2010-10-14 04:05:58
【问题描述】:

如果您在循环中创建 10,000 个字符串,则必须进行大量垃圾收集,这会占用大量资源。

如果你对符号做同样的事情,你会创建cannot be garbage collected的对象。

哪个更糟?

【问题讨论】:

    标签: ruby performance memory garbage-collection symbols


    【解决方案1】:

    由于符号几乎总是通过字面量创建,因此这里内存爆炸的可能性不大。它们的行为在很大程度上是由它们的用法所要求的:每次你引用一个符号时,它都是同一个。

    同样,字符串在 Ruby 中也必须是唯一的。这是由于它们的使用方式 - 文本处理等。

    根据语义决定使用哪一个,不要过早优化。

    【讨论】:

      【解决方案2】:

      如果您在循环中引用相同的符号,则不必每次都重新创建该对象,即

      while i < 10000
        i += 1
        :im_using_this_symbol_here
      end
      

      现在,如果您在此处使用字符串,则该字符串将被重新创建 10K 次。通常,在您几乎将文字视为常量或键的情况下使用符号。对我来说一个很好的例子是

      link_to "News", :action => 'news'
      

      而不是

      link_to "News", "action" => 'news'
      

      在您的应用程序中一遍又一遍地重复使用操作。

      【讨论】:

      • 我可以添加一条经验法则:永远不要将任何用户提供的字符串转换为符号。这将打开 DOS 攻击的可能性。
      【解决方案3】:

      如果您使用的是 Ruby 2.2.0 或更高版本,通常应该可以动态创建大量符号,因为它们将根据 Ruby 2.2.0-preview1 announcement 进行垃圾收集,其中包含指向 more details about the new symbol GC 的链接。但是,如果您将动态符号传递给某种将其转换为 ID(C 源代码中使用的内部 Ruby 实现概念)的代码,那么在这种情况下,它将被固定并且永远不会被垃圾收集。我不确定这种情况发生的频率有多高。

      在决定使用符号还是字符串时,您应该考虑:

      • 符号在创建后无法更改。
      • 符号没有很多字符串有的方法,比如start_with?
      • 可以非常有效地比较符号是否相等。
      • 根据Symbol docs,符号应该代表某物的名称。我不会用它们来存储任何不能被视为名称的东西。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-11-23
        • 1970-01-01
        • 2012-06-12
        • 2017-02-21
        • 2015-12-17
        • 2016-03-16
        • 1970-01-01
        • 2011-04-24
        相关资源
        最近更新 更多