我是通过插入大约1000个用户来测试应用程序的,每个用户在mnesia下的数据库表中都有1000个联系人,在插入某个部分时,我得到的错误如下:
Crash dump was written to: erl_crash.dump
binary_alloc: Cannot allocate 422879872 bytes of memory (of type "binary").
Aborted我用erl +MBas af (B-二进制分配程序af- a fit)启动erl模拟器,然后再试一次,但是错误是相同的,
注意:我正在使用erlang r12b版本,系统ram在ubuntu10.04上是8gb的,所以我可以知道如何解决吗?
记录的定义如下:
%% -record(数据库,{dbid,guid,data}).
%% changelog -record(changelog,{dbid,时间戳,changelist,type})。
这里的数据是一个vcard(联系人信息),dbid和类型是“联系人”,guid是服务器自动生成的整数。
数据库记录包含所有users.if的所有vcard数据,有1000个用户,每个用户有1000个联系人,那么我们将有10^6条记录。
changelog记录将包含该时间戳对数据库表所做的更改。
创建表的代码如下:
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}).发布于 2011-11-23 11:43:51
我认为列表DataList很大,不应该立即从远程节点发送。它应该分几个小块寄出去。客户端可以从客户端生成的DataList逐项发送。另外,由于这个问题发生在插入过程中,我认为我们应该并行处理列表理解。我们可以有一个并行映射,其中对于列表中的每个项目,插入都是在一个单独的过程中完成的。然后,我也认为清单的理解还是有问题的。变量Key未绑定,变量X未使用。否则,整个方法可能需要改变。让我们看看别人怎么想。谢谢
发布于 2011-11-26 11:44:02
当binary_alloc内存分配程序没有为二进制堆分配内存时,通常会发生此错误。使用erlang:system_info()或erlang:memory()或erlang:memory(二进制)命令检查当前二进制堆大小。如果二进制堆大小很大,那么运行erlang:garbage_collect()来释放二进制堆中所有未引用的二进制对象。这将释放记忆..。
发布于 2011-12-01 01:43:36
如果您使用长字符串(只是erlang中的list )作为vcard或其他类型的字符串,它们会消耗大量内存。如果是这样,则将它们更改为二进制,以抑制内存使用(在插入到mnesia之前使用list_to_binary )。
这可能没有帮助,因为我不知道您的数据结构(类型、长度等).
https://stackoverflow.com/questions/8238417
复制相似问题