我有关于Xmb的大量二进制数据iof ip data。进程使用二进制做一些搜索算法来查找ip地址。我有三种方法。
1.投入。但我想每次读取访问都会将大二进制文件复制到进程中。 :(
2.放入gen_server状态。进程使用gen_server:调用获取地址。即将到来的并发性。
3.将二进制编译成波束。但是当我编译得到
eheap_alloc: Cannot allocate 1318267840 bytes of memory (of type "heap")
哪个大数据的最佳实践在erlang中共享?
答案 0 :(得分:3)
大小为are stored as reference counted binaries的64字节以上的二进制文件,它们的数据存储在任何进程的堆之外。如果将此类二进制文件发送到任何进程,则基础数据不重复。因此,如果将这样的二进制文件存储在ETS表中,然后从各种进程访问它,则不会复制基础数据,只会增加/减少其引用计数。我建议使用ETS表解决方案。
这里演示了在将100MB二进制文件插入ETS表之后,以及在将二进制文件的副本提取到shell进程之后启动时的内存使用情况。我们在shell进程中存储了一个副本二进制文件后,内存使用量没有变化。如果它是我们从ETS或其他进程中复制的百万字符串(整数列表),情况就不一样了。
1> erlang:memory().
[{total,21912472},
{processes,5515456},
{processes_used,5510816},
{system,16397016},
{atom,223561},
{atom_used,219143},
{binary,844872},
{code,4808780},
{ets,301232}]
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中有效使用二进制文件的更多信息。