Двоичные файлы размером более 64 байт хранятся как двоичные файлы с подсчетом ссылок, а их данные хранятся вне кучи любого процесса. Если такой двоичный файл отправляется какому-либо процессу, базовые данные не дублируются. Таким образом, если вы сохраните такой двоичный файл в таблице ETS, а затем получите к нему доступ из различных процессов, базовые данные не будут скопированы, а будет увеличиваться/уменьшаться только его счетчик ссылок. Я бы предложил использовать табличное решение ETS.
Вот демонстрация использования памяти при загрузке, после вставки двоичного файла размером 100 МБ в таблицу ETS и после извлечения копии двоичного файла в процесс оболочки. Использование памяти не меняется после того, как у нас есть двоичная копия, сохраненная в процессе оболочки. То же самое было бы неверно, если бы мы копировали строку из миллиона символов (список целых чисел) из 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, по ссылке выше.
person
Dogbert
schedule
01.12.2017