Erlang VM使用了多少内存?

时间:2014-08-20 02:02:49

标签: erlang

我想知道这个数据结构将使用Erlang VM中有多少内存?

[{"3GPP-UTRAN-FDD", [{"utran-cell-id-3gpp","CID1000"}, "1996-12-19t16%3a39%3a57-08%3a00", "1996-12-19t15%3a39%3a27%2e20-08%3a00"]}]

在我的应用程序中,每个进程都会将这些数据存储在自己的循环数据中,此进程的数量将为120000。

我测试的结果:

不要存储这些数据,内存将是:

memory[kB]:  proc 1922806, atom    2138, bin   24890, code   72757, ets  459321

存储这些数据,将会是:

memory[kB]:  proc 1684032, atom    2138, bin   24102, code   72757, ets  459080

所以最大的区别是proc使用的备忘录:(1922806 - 1684032) / 1024 = 233M.

经过研究,我发现了一件令人兴奋的事情:

L = [{"3GPP-UTRAN-FDD", [{"utran-cell-id-3gpp","CID1000"}, "1996-12-19t16%3a39%3a57-08%3a00", "1996-12-19t15%3a39%3a27%2e20-08%3a00"]}].
B = list_to_binary(io_lib:format("~p", L)).   
erts_debug:size(B). % The output is 6

使用二进制文件后内存只使用6个字?怎么解释这个?

2 个答案:

答案 0 :(得分:6)

有两个有用的函数可用于衡量Erlang术语的大小:erts_debug:size/1erts_debug:flat_size/1。这两个函数都以单词形式返回术语的大小。

erts_debug:flat_size/1为您提供没有术语共享优化的邮件总大小。如果将它复制到新堆,则保证为该术语的大小,如消息传递和ets表一样。

erts_debug:size/1为您提供当前流程中的字词大小'堆,允许通过共享重复的术语来优化内存使用。

以下是差异的演示:

1> MyTerm = {atom, <<"binary">>, 1}.
{atom,<<"binary">>,1}
2> MyList = [ MyTerm || _ <- lists:seq(1, 100) ].
[{atom,<<"binary">>,1}|...]
3> erts_debug:size(MyList).
210
4> erts_debug:flat_size(MyList).
1200

正如您所看到的,由于术语共享,尺寸存在显着差异。

至于您的特定术语,我使用了Erlang shell(R16B03)并使用flat_size测量了该术语。根据这个,你的术语的内存使用是:226字(1808B,1.77KB)。

这是一个用于看似简单术语的大量内存,但这超出了本问题的范围。

答案 1 :(得分:3)

当你执行list_to_binary(io_lib:format("~p", L)).时,整个二进制文件的大小是135个字节,如果你在64位系统上,它代表4.375个单词,所以6个单词应该是正确的大小,但是你丢失了直接访问权限内部结构。

奇怪但可以理解:

19> erts_debug:flat_size(list_to_binary([random:uniform(26) + $a - 1 || _ <- lists:seq(1,1000)])).                                                                                  
6                                                                                                                                                                                   
20> erts_debug:flat_size(list_to_binary([random:uniform(26) + $a - 1 || _ <- lists:seq(1,10000)])).                                                                                 
6                                                                                                                                                                                   
21> size(list_to_binary([random:uniform(26) + $a - 1 || _ <- lists:seq(1,10000)])).                                                                                                 
10000                                                                                                                                                                               
22> (list_to_binary([random:uniform(26) + $a - 1 || _ <- lists:seq(1,10000)])).                                                                                                     
<<"myeyrltgyfnytajecrgtonkdcxlnaoqcsswdnepnmdxfrwnnlbzdaxknqarfyiwewlugrtgjgklblpdkvgpecglxmfrertdfanzukfolpphqvkkwrpmb"...>>                                                       
23> erts_debug:display({list_to_binary([random:uniform(26) + $a - 1 || _ <- lists:seq(1,10000)])}).
{<<10000 bytes>>}
"{<<10000 bytes>>}\n"
24>

这意味着erts_debug:flat_size返回变量的大小(大致是类型信息,指向数据及其大小的指针),但不是二进制数据本身的大小。二进制数据存储在别处,可以由不同的变量共享。