Go использует сборщик меток и разверток в его нынешней реализации.
Согласно алгоритму, будет один корневой объект, а остальное - древовидная структура, в случае многоядерных машин gc
запускается вместе с программой на одном ядре.
gc
будет проходить по дереву, а когда что-то недоступно, оно считает его свободным.
Объекты Go также имеют метаданные для объектов, как указано в этом посте .
Выдержка:
Нам нужно было получить некоторую информацию об объектах, поскольку у нас не было заголовков. Биты марки хранятся сбоку и используются для маркировки, а также для распределения. Каждое слово имеет 2 бита, связанных с ним, чтобы сказать вам, было ли это скаляр или указатель внутри этого слова. Он также кодировал, было ли в объекте больше указателей, чтобы мы могли остановить сканирование объектов раньше, чем позже.
Причина, по которой срезы go (заголовок среза) были структурами вместо указателя на структуры, задокументированы русским коксом на этой странице в разделе срезов.
Это выдержка:
Изначально Go представлял слайс как указатель на структуру (заголовок слайса), но это означало, что каждая операция слайса выделяла новый объект памяти. Даже с быстрым распределителем это создает много ненужной работы для сборщика мусора, и мы обнаружили, что, как и в случае со строками, программы избегали операций среза в пользу передачи явных индексов. Удаление косвенной ссылки и выделения сделало срезы достаточно дешевыми, чтобы избежать передачи явных индексов в большинстве случаев.
Размер (длина) массива является частью его типа. Типы [1]int
и [2]int
различны.
Следует помнить, что go - это ориентированный на ценность язык, вместо хранения указателей, они хранят прямые значения.
[3]int
, массивы являются значениями в go, поэтому, если вы передадите массив, он скопирует весь массив.
[3]int
это значение (одно целое).
Когда вы делаете a[1]
, вы получаете доступ к части значения.
SliceHeader
В поле данных указано, что это базовая точка массива, а не a[0]
Насколько мои знания считаются:
При запросе a[4]
,
a[0]+(sizeof(type)*4)
рассчитывается.
Теперь, если вы получаете доступ к чему-либо через ломтик s = a[2:4]
,
и если кто-то запрашивает s[1]
, он запрашивает:
a[2]+sizeof(type)*1