2012-01-31 4 views
3

私はすべて1)NIFライブラリをロードし、2)新しい/ 0メソッドを実行し、3)F()ですべてを解放してから、 4)erlang:ガベージ:collect()私がメモリに関して始まったところに戻るだろう。実際、私は記憶を漏らしています。明らかに、私のコードは、最も可能性の高い容疑者です。NIFを使用するときに正しくガベージコレクトするには

私が間違っていることを誰かに教えてもらえますか?

私は次の構造を持っている:

static ERL_NIF_TERM new_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) 
{ 
ERL_NIF_TERM term; 
    Node *Head = (Node *)enif_alloc_resource(NODE_RESOURCE,sizeof(Node)); 

    Head->Next = 0; 
    term = enif_make_resource(env, Head); 
    enif_release_resource(Head); 

    return enif_make_tuple2(env, enif_make_atom_len(env, "ok", 2), term); 
} 

と:オンロード

typedef struct Node 
{ 
    int Key; 
    ERL_NIF_TERM TermPtr; 
    struct Node *Next; 
} Node; 

私は、リソース

int on_load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) 
{ 
    ErlNifResourceFlags flags = (ErlNifResourceFlags)(ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER); 
    NODE_RESOURCE = enif_open_resource_type(env, "linkedlist_nif", 
         "node_resource", 
         &node_dtor, 
         flags, 
         0); 
} 

新しい/ 0このNIFにマッピングされます開きますdestructまたはリソースの場合は、次のようになります。

static void node_dtor(ErlNifEnv* env, void* arg) 
{ 
    Node* handle = (Node*)arg; 

    enif_release_resource(handle); 
    handle = NULL; 
} 

答えて

3

だからシェルで、あなたは、あなたがf().次にあなたerlang:garbage_collect().と値を解放し、あなたが開始する前とあなたのメモリ使用量は同じ(っぽい)となることを期待しA = your_nif:new().と値を作成しますか?

これは、シェルが以前の実行結果の履歴を保持しているために発生する可能性があります。これにより、f().garbage_collect().の間に生き残っている言葉への参照が保持されるので、予想通りのメモリ動作は見られません。これはあなたのテストの際に使用されるメモリのいくつかの近似表示する必要があります

Before = erlang:memory(). 
Pid = spawn(fun() -> 
    A = your_nif:new(), 
    receive 
    cleanup -> ok 
    end 
end). 
timer:sleep(timer:seconds(1)). % Wait for pid to spawn and allocate term. 
During = erlang:memory(). 
Pid ! cleanup. 
After = erlang:memory(). 

lists:zipwith3(fun ({K, B}, {K, D}, {K, A}) -> 
       {K, _Values = {B, D, A}, {_Leaked = A - B, _Used = D - B}} end, 
       Before, During, After). 

(厳密には正確ではないが、しかしyour_nif:new()用語が十分に大きい場合には、他のメモリ割り当てを日食ます):

あなたのような何かができますその後、漏れた。

+1

もっと簡単なアプローチ履歴にストア値を避ける方法: 'A = your_nif:new()、ok.' –

関連する問題