Уничтожение структуры данных, когда программе она больше не нужна - Erlang - PullRequest
0 голосов
/ 13 декабря 2011

Некоторые функции, которые манипулируют Tuples в Erlang , приводят к копированию новых кортежей после операции.В большинстве случаев программа больше не интересуется старой копией кортежа, из которой была сделана новая.Давайте рассмотрим пример:

change(Position,Tuple1,NewValue) when size(Tuple1) > 10,Position < 10 ->
    NewTuple = erlang:setelement(Position, Tuple1, NewValue),
    %% at this point i don't want <b>Tuple1</b>
    %% I want to destroy <b>Tuple1</b> at this point !
    %% how do i do it
    erlang:send(myprocess,NewTuple),
    ok.

В приведенном выше примере я создаю новый кортеж из существующего.Если я собираюсь сделать это впоследствии, я бы хотел уничтожить старые копии сам.У меня есть ощущение, что система компилятора / среды выполнения делает это автоматически, но если бы это было так, они бы не дали нам такие функции, как: erlang:garbage_collect/0.Я уверен, что они поняли, что нам, возможно, понадобится неявно управлять нашей памятью, возможно, это спасет программу от сбоев и обойдет часть кода, интенсивно использующую память.

Я понимаю, чтов erlang shell можно заставить его забыть переменную (я предполагаю, что они имели в виду уничтожить переменную), используя f/0, f/1.Тем не менее, кажется, я не могу использовать это в моих модулях / функциях.У меня также есть сомнения, что размещение подчеркивания перед этим именем переменной может ускорить уничтожение системой времени выполнения, то есть где-то в моем коде пишется: _Tuple1 для уничтожения Tuple1

.Таким образом, вопрос в том, если я впоследствии собираюсь создавать кортежи из существующих и на каждом шаге я хочу немедленно (сам) уничтожать старые копии, как мне это сделать? * Примечание * Я понимаю, что руководство по эффективности запрещает это, но, если у меня нет выбора .....

Ребята, помогите, каково ваше решение для этого?спасибо

Ответы [ 2 ]

8 голосов
/ 13 декабря 2011

Компилятор легко обнаруживает, что после:

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

Tuple1 больше не упоминается здесь и удалит свою ссылку на него. Нет необходимости пытаться помочь ему в этом, я гарантирую, что он справится с этим лучше, чем вы или я. В следующий раз, когда будет сборка мусора, и если нет других ссылок на нее, она будет исправлена , На самом деле сборщик не «уничтожает старые копии» , а просто помечает данные как свободные, чтобы их можно было использовать повторно. Невозможно сделать это самостоятельно, что очень хорошо! Это могло бы помешать нормальному выделению памяти / сборке мусора, если бы это происходило вне его обычной обработки.

Что еще более важно, именно этого явного управления памятью мы хотим избежать, именно поэтому все это происходит автоматически. Динамические ошибки памяти - все это легко сделать, а потом трудно найти. Например, в этом случае, как вы ЗНАЕТЕ , я имею в виду 100% -ную уверенность ДЕЙСТВИТЕЛЬНО ЗНАНИЯ , что на этот кортеж больше не ссылаются, поэтому он может быть освобожден? Сборщик мусора знает. Так что оставь это коллекционеру. Серьезно.

Вызов erlang:garbage_collect/0 запускает сборщик немного раньше, но редко требуется делать это явно.

1 голос
/ 13 декабря 2011

Нет способа сделать это.Вызов erlang:garbage_collect/0 в этот момент также не уничтожит Tuple1, поскольку он все еще доступен из стека.

...