有人可以解释为什么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?!
为什么s2
比s
短得多的字符串
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!?
为什么这些字符串的大小与它们的长度不匹配?
谢谢
答案 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。