Может кто-нибудь объяснить, почему 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

Но в его размере больше 3 слов, чем s?

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

И почему размер этих струн не соответствует их длине?

Благодарность

2
mljrg 6 Ноя 2018 в 19:58

1 ответ

Лучший ответ

Первая подсказка, почему это показывает, что значения можно найти в этот вопрос. Цитата 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 о реализации битовых строк .


Итак, в первом случае строка слишком велика, чтобы поместиться только в куче, поэтому используется двоичные файлы refc, которые хранятся в стеке , а в куче есть только указатель на данный двоичный файл.

Во втором случае строка короче 64 байтов и использует двоичные файлы кучи который представляет собой просто массив байтов, хранящихся непосредственно в куче, что дает нам 8 bytes per word (64-bit) * 9 = 72, и когда мы проверяем документацию о точных накладных расходах памяти в виртуальной машине, мы видим, что Erlang использует 3..6 слов на двоичный код + data, где данные могут быть переданы.

3
Hauleth 6 Ноя 2018 в 18:04