Распределение памяти мнезии
Я тестировал приложение, вставив около 1000 пользователей и каждого пользователя, имеющего 1000 контактов, в таблицу базы данных в mnesia, и во время вставки в какой-то части я получил следующую ошибку:
Crash dump was written to: erl_crash.dump
binary_alloc: Cannot allocate 422879872 bytes of memory (of type "binary").
Aborted
я запустил эмулятор erl с erl + MBas af (B-бинарный распределитель подходил) и попробовал снова, но ошибка была та же,
примечание:: я использую версию erlang r12b, а системная оперативная память на ubuntu 10.04 составляет 8 ГБ, так что я могу знать, как ее решить?
определения записей:
%% database-record (база данных, {dbid, guid, data}).
%% changelog-record (changelog, {dbid, отметка времени, список изменений, тип}).
здесь данные - vcard(контактная информация), dbid и тип - "контакты", guid - целое число, автоматически генерируемое сервером
запись базы данных содержит все данные vcard всех пользователей. если есть 1000 пользователей и каждый пользователь имеет 1000 контактов, то у нас будет 10^6 записей.
запись журнала изменений будет содержать информацию о том, какие изменения были внесены в таблицу базы данных в этот момент времени.
код для создания таблиц:
mnesia:create_table(database, [{type,bag}, {attributes,Record_of_database},
{record_name,database},
{index,guid},
{disc_copies,[node()]}])
mnesia:create_table(changelog, [{type,set}, {attributes,Record_of_changelog},
{record_name,changelog},
{index,timestamp},
{disc_copies,[node()]}])
вставка записей в таблицу:
commit_data(DataList = [#database{dbid=DbID}|_]) ->
io:format("commit data called~n"),
[mnesia:dirty_write(database,{database,DbId,Guid,Key})|| {database,DbId,Guid,X}<-DataList].
write_changelist(Username,Dbname,Timestamp,ChangeList) ->
Type="contacts",
mnesia:dirty_write(changelog,{changelog,DbID,Timestamp,ChangeList,Type}).
3 ответа
Если вы используете длинные строки (это просто список в erlang) для vcard или кого-то еще, они занимают много памяти. В этом случае вы изменяете их на двоичные, чтобы подавить использование памяти (используйте list_to_binary перед вставкой в mnesia).
Это может быть бесполезно, потому что я не знаю о вашей структуре данных (тип, длина и т. Д.)...
Эта ошибка обычно возникает, когда нет памяти для выделения для двоичной кучи с помощью распределителя памяти ERTS, называемого binary_alloc. Проверьте текущий размер двоичной кучи с помощью команд erlang:system_info() или erlang:memory() или erlang:memory(binary). Если размер двоичной кучи огромен, то запустите erlang:garbage_collect(), чтобы освободить все двоичные объекты, на которые нет ссылок, в двоичной куче. Это освободит память..
Я полагаю, что список DataList
огромен и не должен быть отправлен сразу с удаленного узла. Он должен быть отправлен небольшими кусочками. Клиент может отправить один за другим элемент из списка данных, сгенерированного на клиенте. Кроме того, поскольку эта проблема возникает во время вставки, я думаю, что мы должны распараллелить понимание списка. У нас может быть параллельная карта, где для каждого элемента в списке вставка выполняется в отдельном процессе. Затем я также думаю, что что-то не так с пониманием списка. переменная Key
является несвязанным и переменным X
не используется. В противном случае, вероятно, вся методология нуждается в изменении. Давайте посмотрим, что думают другие. Спасибо