当程序不再需要数据结构时销毁它——Erlang

当程序不再需要数据结构时销毁它——Erlang,erlang,mnesia,yaws,mochiweb,nitrogen,Erlang,Mnesia,Yaws,Mochiweb,Nitrogen,在中操作元组的某些函数会在操作后生成新元组的副本。在大多数情况下,程序不再对从中生成新元组的旧元组副本感兴趣。让我们看一个例子: change(Position,Tuple1,NewValue) when size(Tuple1) > 10,Position < 10 -> NewTuple = erlang:setelement(Position, Tuple1, NewValue), %% at this point i don't want Tuple1

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

change(Position,Tuple1,NewValue) when size(Tuple1) > 10,Position < 10 -> NewTuple = erlang:setelement(Position, Tuple1, NewValue), %% at this point i don't want Tuple1 %% I want to destroy Tuple1 at this point ! %% how do i do it erlang:send(myprocess,NewTuple), ok. 当大小(Tuple1)>10,位置<10-> NewTuple=erlang:setelement(位置,Tuple1,NewValue), %%在这一点上,我不想要Tuple1 %%我想在这一点上摧毁Tuple1! %%我该怎么做 erlang:send(myprocess,NewTuple), 好啊 在上面的示例中,我从现有元组创建了一个新元组。如果我以后要这么做,我想销毁我自己的旧拷贝。我有一种感觉,编译器/运行时系统会自动执行此操作,但如果是这样,他们就不会给我们提供诸如:
erlang:garbage\u collect/0
之类的函数。我确信他们意识到我们可能需要隐式地管理内存,这可能会使程序免于崩溃,并通过代码中内存密集的部分找到出路。

我知道在
erlangshell
中,可以使用
f/0、f/1
使其忘记变量(我假设他们的意思是销毁变量)。但是,我似乎无法在我的模块/函数中使用此功能。我还怀疑,在变量名前加下划线可能会加速运行时系统的销毁,即我的代码中的某些地方被写入:
\u Tuple1
销毁
Tuple1

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


伙计们,帮帮忙,你有什么办法?谢谢

没有办法。此时调用
erlang:garbage\u collect/0
也不会破坏
Tuple1
,因为它仍然可以从堆栈访问。

编译器很容易检测到:

    NewTuple = erlang:setelement(Position, Tuple1, NewValue),
Tuple1
不再在此引用,将删除其链接。没有必要尝试帮助它做到这一点,我保证它比你或我做得更好。下次有垃圾收集,如果没有其他引用,它将被回收。实际上,收集器不会“销毁旧拷贝”,而只是将数据标记为自由数据,以便重新使用。这是一件非常好的事情,你自己是无法做到的!如果这是在其正常处理之外进行的,则会干扰正常的内存分配/垃圾回收

更重要的是,这种显式内存管理正是我们想要避免的事情,这就是为什么它都是自动完成的。动态内存错误都很容易制造,之后很难找到。例如,在本例中,您如何知道,我的意思是100%确定真正知道,该元组不在其他任何地方引用,因此可以自由回收?垃圾收集器知道。那就交给催收员吧。真的


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

rvirding下面的回答非常正确。如果您在内存使用方面有问题,最好是问一个新问题,您试图描述您的程序的功能以及问题的详细症状。仅仅使用元组很少是一个问题。您是否使用了非常大的元组,因为您担心元组的销毁速度不够快?问题中的元组很小,但我有一部分需要根据用户的操作或选择重置元组中的值。所以,我想知道情况会有多糟。当我读到函数
setelement/3
时,我说了
copy
这个词,这让我很担心。如果服务器获得更多的连接并且元组被复制,那么运行时系统还会帮助我以复制的速度对它们进行垃圾收集多久?但现在我明白了。尽管如此,我仍在尝试使用
列表理解来解决这个问题