【问题标题】:Big binary data share between processes进程间大二进制数据共享
【发布时间】:2018-05-15 16:07:38
【问题描述】:

我有一个关于 Xmb 的大二进制数据 iof ip 数据。进程使用二进制执行一些搜索算法来查找 IP 地址。我有三种方法。 1.放入ets。但我想每次读取访问都会复制大二进制文件来处理。 :( 2. 进入 gen_server 状态。进程使用 gen_server:call 来获取地址。短的并发。 3. 将二进制编译成beam。但是当我编译得到 eheap_alloc: Cannot allocate 1318267840 bytes of memory (of type "heap")

erlang中大数据的最佳实践有哪些分享?

【问题讨论】:

  • 抱歉排版不好。

标签: binary erlang ets


【解决方案1】:

大小超过 64 字节的二进制文件 are stored as reference counted binaries 及其数据存储在任何进程的堆外。如果将这样的二进制文件发送到任何进程,则底层数据不会重复。因此,如果您将此类二进制文件存储在 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 中高效使用二进制文件的信息。

【讨论】:

  • 什么是 processes_used 在查找后增加了大约 482040 字节?我曾经假设它会在插入后增加 ets 中相同的内存,但 ets 只增加了 7184 字节。
  • 值一直在小幅波动,因为事情总是在后台运行,垃圾收集器也是如此。 ETS 的内存没有增加,因为二进制文件存储在“二进制”堆中。 ETS 仅存储对二进制文件的引用,就像处理大型二进制文件时所做的一样。
  • 3q 为您解答
猜你喜欢
  • 1970-01-01
  • 2018-01-01
  • 2020-10-30
  • 2013-05-05
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-27
相关资源
最近更新 更多