0

ErlangTuplesで操作する特定の関数は、操作後に新しいタプルのコピーになります。ほとんどの場合、プログラムは、新しいタプルのコピーが作成された古いタプルのコピーには関心がありません。例を見てみましょう:

size(Tuple1)> 10、Position <10->の場合、change(Position、Tuple1、NewValue)
    NewTuple = erlang:setelement(Position、Tuple1、NewValue)、%%この時点でTuple1
    は必要ありません%%この時点でTuple1
    を破棄したいです!
    %% どうすればいいのですか
    erlang:send(myprocess、NewTuple)、
    わかった。

上記の例では、既存のタプルから新しいタプルを作成します。後でこれを行う場合は、古いコピーを自分で破棄したいと思います。コンパイラ/ランタイムシステムがこれを自動的に行うように感じますが、そうであれば、次のような関数は提供されませんでしたerlang:garbage_collect/0。暗黙的にメモリを管理する必要があるかもしれないことを彼らは理解していると確信しています。おそらく、プログラムがクラッシュするのを防ぎ、コードのメモリを大量に消費する部分を通り過ぎてしまうでしょう。

で、を使用して変数を忘れさせることができることを理解してerlang shellいます(変数を破棄することを意味していると想定しています)f/0, f/1。ただし、モジュール/関数でこれを使用できないようです。また、その変数名の前にアンダースコアを付けると、ランタイムシステムによる破棄が早まる可能性があることにも疑問があり_Tuple1ます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 に答える