【问题标题】:How Erlang atoms can be garbage collectedErlang 原子如何被垃圾回收
【发布时间】:2013-12-29 08:33:54
【问题描述】:

据说原子不会被垃圾收集。一旦你创建了一个 atom,它就会保留在 atom 表中,这最终可能会导致内存泄漏!

我对 Erlang 还很陌生,我的问题是:如何对原子进行垃圾收集?如果不可能,如何最小化这种影响?

【问题讨论】:

    标签: garbage-collection erlang


    【解决方案1】:

    除非您动态创建原子,否则原子不是问题。如果你这样做了,那么你正在使 Erlang 系统崩溃。

    如何动态创建原子? 例如在循环中调用 list_to_atom 函数。

    如果您对 Erlang 垃圾回收感兴趣,请阅读 Joe Armstrong 的这篇论文:One Pass Real-Time Generational Mark-Sweep Garbage Collection (1995)

    始终牢记:不要动态创建 Atom!
    好吧,有时您可能需要动态创建 Atom,但不要过度使用它!

    【讨论】:

    • 感谢您的回答。我的问题是:如果它发生并且我动态使用它们,我怎样才能释放它们的内存?
    • 内存泄漏的风险很小,因为不同原子的数量是有限的。所以你会在你遇到内存消耗问题之前遇到这个问题(默认情况下,原子的最大数量是1 048 576
    • 好吧,我对 VM 的行为不再有信心,我尝试了这个:[list_to_atom(integer_to_list(X)) || X <- lists:seq(1,1048577)]. 在 shell 中,它无限期地挂起,而具有 1 000 000 个原子的相同循环工作正常。
    • 澄清一下,“不要过度使用它” 意味着只有在知道要创建的原子数量有上限时才应该使用它。例如,在有效的 HTML 文档中为元素名称创建原子的上限是 HTML 标准中定义的元素类型的数量。
    【解决方案2】:

    虽然我不确定原子是否会被垃圾收集,但您可以轻松做到这一点,而不必担心是否会炸毁系统的内存。正如@Chiron 所说,只要在编译时知道所有原子,就可以了。

    如果我真的需要以某种方式使用list_to_atom/1 怎么办?好吧,您也许可以使用这种功能来扭转您的问题:

    atom("apple") -> apple;
    atom("orange") -> orange;
    atom("banana") -> banana.
    

    另一种解决方法是list_to_existing_atom/1

    但是 VM 仍然可以吃越来越多的 RAM:其他连接的 Erlang 节点可能会全局注册原子,即在运行时分配原子。

    【讨论】:

      【解决方案3】:

      来自learn you some Erlang

      Atom 非常好,是发送消息或代表的好方法 常数。然而,使用太多原子是有缺陷的 事物:原子在“原子表”中被引用,它消耗 内存(在 32 位系统中为 4 字节/原子,在 64 位系统中为 8 字节/原子 系统)。原子表不会被垃圾回收,因此原子会 累积直到系统崩溃,无论是内存使用还是 因为声明了 1048577 个原子。

      这意味着原子不应该被动态生成 原因;如果您的系统必须可靠并且用户输入允许某人 通过告诉它创建原子随意崩溃它,你是认真的 麻烦。原子应该被视为开发人员的工具,因为 老实说,他们就是这样。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-02-11
        • 1970-01-01
        • 2013-11-16
        • 2012-06-23
        • 2020-05-11
        • 1970-01-01
        • 1970-01-01
        • 2017-01-19
        相关资源
        最近更新 更多