Certain functions that manipulate Tuples
in Erlang, result into copies of new tuples after the operation. In most cases, the program is no longer interested in the old tuple copy from which a new one was made. lets look at an example:
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.
In the example above, i create a new tuple from an existing one. If am to do this subsequently, i would want to destroy the old copies my self. I have a feeling that the compiler/ runtime system does this automatically, but if it were so they would not have given to us functions such as: erlang:garbage_collect/0
. Am sure they realised that we may need to implicitly manage our memory, probably it would save a program from crashing and find its way past a memory intensive part of the code.
I understand that in the erlang shell
, its possible to make it forget a variable (am assuming that what they meant is to destroy the variable) using f/0, f/1
. However, it seems i cannot use this in my modules/functions. I also have doubts that putting an underscore infront of that variable name may hasten the destruction by the runtime system i.e. some where in my code is write: _Tuple1
to destroy Tuple1
. In summary, the question is that, if am subsequently going to create tuples from existing ones and at each step i want to destroy the old copies immediately (myself), how do i do it ? * Note * i understand that the efficiency guide prohibits this but, if i have no choice.....
Guys help, whats your solution to this? thanks
The compiler easily detects that after:
NewTuple = erlang:setelement(Position, Tuple1, NewValue),
Tuple1
is no longer referenced here and will remove its link to it. There is no need to try and help it do this, I guarantee that it does a better job of it than you, or I. The next time there is a garbage collection and if there are no other references to it then it will be reclaimed. Actually the collector does not "destroy old copies" but just marks the data as free so it can be reused. There is no way of doing this explicitly yourself which is a very Good Thing! It would interfere with the normal memory allocation/garbage collection if this were going on outside its normal processing.
More importantly this explicit memory management is the very thing we want to avoid, which is why it is all done automatically. Dynamic memory bugs are all to easy to make and all to difficult to find afterwards. For example in this case how do you KNOW, I mean to 100% certainty REALLY KNOW, that this tuple is not referenced anywhere else so it is free to be reclaimed? The garbage collector knows. So leave it to it to the collector. Seriously.
Calling erlang:garbage_collect/0
runs the collector a bit sooner but there is seldom need to do this explicitly.