Точная работа сборки мусора и выделения памяти известна лишь немногим. К счастью, они очень рады поделиться своими знаниями, и следующее основано на том, что я узнал из списка рассылки erlang-questions и обсуждения с разработчиками OTP.
При обмене сообщениями между процессами содержимое всегда копируется, поскольку между процессами нет общей кучи. Единственным исключением являются двоичные файлы размером более 64 байт, в которые копируется только ссылка.
При выполнении кода в одном процессе обновляются только части. Давайте проанализируем кортежи, как пример, который вы предоставили.
Кортеж - это фактически структура, которая хранит ссылки на реальные данные где-то в куче (за исключением маленьких целых чисел и, возможно, еще одного типа данных, который я не могу вспомнить). Когда вы обновляете кортеж, используя, например, setelement/3
, создается новый кортеж с заменой данного элемента, однако для всех остальных элементов копируется только ссылка. Существует одно исключение , которым я никогда не смог воспользоваться.
Сборщик мусора отслеживает каждый кортеж и понимает, когда безопасно вернуть любой кортеж, который больше не используется. Возможно, данные, на которые ссылается кортеж, все еще используются, и в этом случае сами данные не собираются.
Как всегда, Эрланг дает вам несколько инструментов, чтобы точно понять, что происходит. Руководство по эффективности подробно описывает, как использовать erts_debug:size/1
и erts_debug:flat_size/1
, чтобы понять размер структуры данных при внутреннем использовании в процессе и при копировании. Инструменты трассировки также позволяют понять, когда, что и сколько было собрано мусора.