0

TuplesErlang中操作的某些函数会在操作后生成新元组的副本。在大多数情况下,程序不再对创建新元组的旧元组副本感兴趣。让我们看一个例子:

当 size(Tuple1) > 10,Position < 10 -> 时改变(Position,Tuple1,NewValue)
    NewTuple = erlang:setelement(Position, Tuple1, NewValue),
    %% 在这一点上我不想要Tuple1 
    %% 我现在想销毁Tuple1!
    %% 我该怎么做
    二郎:发送(myprocess,NewTuple),
    好的。

在上面的示例中,我从现有的元组创建了一个新元组。如果我随后这样做,我想销毁我自己的旧副本。我有一种感觉,编译器/运行时系统会自动执行此操作,但如果是这样的话,他们就不会为我们提供以下功能:erlang:garbage_collect/0. 确信他们意识到我们可能需要隐式管理我们的内存,这可能会使程序免于崩溃并找到通过代码的内存密集部分的方式。

我知道在 中erlang shell,有可能使用f/0, f/1. 但是,似乎我不能在我的模块/功能中使用它。我也怀疑在该变量名前面加上下划线可能会加速运行时系统的破坏,即我的代码中的某些地方 write: _Tuple1to destroy Tuple1

。总之,问题是,如果我随后要从现有的元组创建元组,并且在每一步我想立即(我自己)销毁旧副本,我该怎么做? * 注意 *我知道效率指南禁止这样做,但是,如果我别无选择......

各位大神帮忙看看有什么解决办法吗?谢谢

4

2 回答 2

8

编译器很容易检测到:

    NewTuple = erlang:setelement(Position, Tuple1, NewValue),

Tuple1此处不再引用,并将删除其指向它的链接。没有必要尝试帮助它这样做,我保证它比你或我做得更好。下次有垃圾收集时,如果没有其他对它的引用,那么它将被回收. 实际上,收集器不会“销毁旧副本”,而只是将数据标记为免费,以便可以重复使用。自己没有办法明确地做到这一点,这是一件非常好的事情!如果这在其正常处理之外进行,它将干扰正常的内存分配/垃圾收集。

更重要的是,这种显式的内存管理正是我们想要避免的,这就是为什么这一切都是自动完成的。动态内存错误都很容易制造,而且之后很难找到。例如,在这种情况下,你怎么知道,我的意思是 100% 确定真的知道,这个元组在其他任何地方都没有被引用,所以它可以被免费回收?垃圾收集器知道。所以留给收藏家吧。严重地。

调用erlang:garbage_collect/0会更快地运行收集器,但很少需要显式执行此操作。

于 2011-12-13T12:35:15.853 回答
1

没有办法做到这一点。此时调用erlang:garbage_collect/0也不会破坏Tuple1,因为它仍然可以从堆栈中访问。

于 2011-12-13T11:32:03.097 回答