Elixir / Erlang中字符串的长度和大小需要说明

时间:2018-11-06 16:58:25

标签: erlang elixir

有人可以解释为什么s是具有4096个字符的字符串

iex(9)> s = String.duplicate("x", 4096)
... lots of "x"
iex(10)> String.length(s)
4096

但是它的内存大小只有6个字?

iex(11)> :erts_debug.size(s)
6 # WHAT?!

为什么s2s短得多的字符串

iex(13)> s2 = "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20"
"1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20"
iex(14)> String.length(s)
50

但是它的大小比s多3个字?

iex(15)> :erts_debug.size(s2)
9 # WHAT!?

为什么这些字符串的大小与它们的长度不匹配?

谢谢

1 个答案:

答案 0 :(得分:2)

第一个提示,这表明在this question中可以找到值。引用size/1文档:

%% size(Term)
%%  Returns the size of Term in actual heap words. Shared subterms are
%%  counted once.  Example: If A = [a,b], B =[A,A] then size(B) returns 8,
%%  while flat_size(B) returns 12.

可以在Erlang documentation about bitstrings implementation中找到第二条线索。


因此,在第一种情况下,字符串太大而无法单独放在堆上,因此它使用refc binaries,它们存储在 stack 上,并且在堆上只有指向给定二进制数的指针。

在第二种情况下,字符串小于64个字节,并且它使用heap binaries,它只是直接存储在堆中的字节数组,因此当我们检查有关确切内存的文档时,这给了我们8 bytes per word (64-bit) * 9 = 72 VM中的开销,我们看到Erlang uses 3..6 words per binary + data, where data can be shared