распределение памяти в памяти

Я тестировал приложение, вставляя около 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-двоичный распределитель af- a fit) и попытался снова, но ошибка была такой же,

примечание :: я использую версию erlang r12b, а системная оперативная память составляет 8 ГБ на ubuntu 10.04, могу ли я узнать, как решить эту проблему?

определения записей:

%% database -record (база данных, {dbid, guid, data}).

%% changelog -record (журнал изменений, {dbid, отметка времени, список изменений, тип}).

здесь данные - это vcard (контактная информация), dbid и type - это контакты, 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}).

person satya    schedule 23.11.2011    source источник
comment
Покажите нам свои определения записей и структуры таблиц. Обычно, когда вы используете очень длинные списки как часть пользовательской записи, и у вас плохой способ добавления к ней. Это должно быть связано с тем, что вы можете неправильно использовать определенную структуру данных. Измените свой вопрос, включив в него все определения записей и таблиц, чтобы мы могли сообщить вам, в чем проблема. Кроме того, отредактируйте, чтобы показать фрагмент кода, который создает и вставляет запись пользователя в mnesia, как вы вставляете 1000 контактов. Нам нужно увидеть все это, прежде чем мы сможем продолжить. Покажи нам это, пожалуйста, спасибо   -  person Muzaaya Joshua    schedule 23.11.2011


Ответы (3)


Я полагаю, что список DataList огромен, и его не следует отправлять сразу с удаленного узла. Его следует отправлять небольшими частями. Клиент может отправлять один за другим элемент из списка данных, созданного на клиенте. Кроме того, поскольку эта проблема возникает во время вставки, я думаю, что нам следует распараллелить понимание списка. У нас может быть параллельная карта, где для каждого элемента в списке вставка выполняется в отдельном процессе. Тогда я также думаю, что что-то все еще не так с пониманием списка. Переменная Key не связана, а переменная X не используется. В противном случае, вероятно, потребуется изменить всю методологию. Посмотрим, что думают другие. Спасибо

person Muzaaya Joshua    schedule 23.11.2011
comment
1) у меня есть отдельная таблица для пользователей, которая используется только на начальном этапе, поэтому я не упоминал об этом, 2) здесь ключ и значение X одинаковы 3) значение dbid - это контакты 4) я поддерживаю 2 узла, один - база данных узел называется dbnode, а другой узел-получатель, который анализирует, принимает и отправляет данные. эти два узла взаимодействуют через вызовы rpc. dbnode содержит все данные приложения. 5) список данных отправляется от клиента, я обрабатываю его и выделяю значение guid и key и делаю вызов rpc для данных фиксации dbnode и последних журналов - person satya; 23.11.2011
comment
Ключ и X могут быть сопоставлены в понимании списка, только если он привязан. Key не связан, но X is bound. Понимание этого списка неверно. Если переменная Key не была также связана с чем-то, мне кажется, что понимание списка все еще необходимо изучить. Но в любом случае это не то, что вызывает проблемы с памятью. Посмотри на мой ответ править - person Muzaaya Joshua; 23.11.2011
comment
на самом деле это должно быть написано [mnesia: dirty_write (database, {database, DbId, Guid, Key}) || {database, DbId, Guid, Key} ‹- DataList] Я заменил значение ключа X. извините за неудобство - person satya; 23.11.2011

Эта ошибка обычно возникает, когда нет памяти, которую нужно выделить для двоичной кучи с помощью распределителя памяти ERTS, называемого binary_alloc. Проверьте текущий размер двоичной кучи с помощью команд erlang: system_info () или erlang: memory () или erlang: memory (двоичных). Если размер двоичной кучи огромен, запустите erlang: garbage_collect (), чтобы освободить все двоичные объекты, на которые нет ссылок, в двоичной куче. Это освободит память ..

person Lakshmi Narasimham    schedule 26.11.2011

Если вы используете длинные строки (это просто список в erlang) для vcard или чего-то еще, они потребляют много памяти. В этом случае вы меняете их на двоичные, чтобы подавить использование памяти (используйте list_to_binary перед вставкой в ​​mnesia).

Это может быть бесполезно, потому что я не знаю вашей структуры данных (тип, длина и т. Д.) ...

person shino    schedule 01.12.2011