2017-12-01 18 views
2

私はXmbに関する大きなバイナリデータiof ipデータを持っています。プロセスバイナリを使用していくつかの検索アルゴリズムをIPアドレスを検索します。私には3つの方法があります。 1. etsを入力します。しかし、私はすべての読み取りアクセスが処理するために大きなバイナリをコピーすると思います。 :(gen_server状態で 2.プットは、プロセスがgen_serverを使用します。。address.The短い来て並行性を取得するために呼び出す 3.コンパイルバイナリビームに私は eheap_alloc: Cannot allocate 1318267840 bytes of memory (of type "heap")プロセス間の大きなバイナリデータ共有

たビッグデータのベストプラクティスを取得するコンパイルするとき。 Erlangでシェア!

+0

悪い組版のために申し訳ありません。 –

答えて

2

サイズare stored as reference counted binariesで64バイトを超えるバイナリとそれらのデータは、任意のプロセスのヒープ外に格納されている。そのようなバイナリは、任意のプロセスに送信されている場合は、基礎となるデータが重複しないである。だから、あなたの場合そのようなバイナリをETSテーブルに格納し、それをさまざまなプロセスからアクセスすると、基礎となるデータはコピーされず、参照カウントだけがインクリメントされますented/decremented。私は、ETSテーブルソリューションをお勧めします。

100MBのバイナリをETSテーブルに挿入し、バイナリのコピーをシェルプロセスにフェッチした後の、ブート時のメモリ使用量のデモンストレーションです。シェルプロセスにコピーバイナリが保存されても、メモリ使用量は変わりません。 ETSや他のプロセスからコピーしていた100万文字列(整数のリスト)であれば、同じことは当てはまりません。

1> erlang:memory(). 
[{total,21912472}, 
{processes,5515456}, 
{processes_used,5510816}, 
{system,16397016}, 
{atom,223561}, 
{atom_used,219143}, 
{binary,844872}, 
{code,4808780}, 
{ets,3}] 
2> ets:new(foo, [named_table, set]). 
foo 
3> ets:insert(foo, {foo, binary:copy(<<".">>, 104857600)}). 
true 
4> erlang:memory(). 
[{total,127038632}, 
{processes,5600320}, 
{processes_used,5599952}, 
{system,121438312}, 
{atom,223561}, 
{atom_used,220445}, 
{binary,105770576}, 
{code,4908097}, 
{ets,308416}] 
5> X = ets:lookup(foo, foo). 
[{foo,<<"........................................................................................................"...>>}] 
6> erlang:memory(). 
[{total,127511632}, 
{processes,6082360}, 
{processes_used,6081992}, 
{system,121429272}, 
{atom,223561}, 
{atom_used,220445}, 
{binary,105761504}, 
{code,4908097}, 
{ets,308416}] 

Erlangのバイナリを効率的に使用する方法については、上記のリンクをご覧ください。

+0

検索後のprocesses_usedは約482040バイト増加しましたか?挿入後にetsのメモリを増やすと仮定しましたが、etsは7184バイトしか増加しません。 –

+0

値は常にバックグラウンドで実行され、ガベージコレクタは常に実行されるため、少量ずつ変動し続けます。バイナリが "バイナリ"ヒープに格納されているため、ETSのメモリは増加しませんでした。 ETSは、大きなバイナリを持っているときと同じように、バイナリへの参照だけを格納します。 – Dogbert

+0

あなたの答えは3q –

関連する問題