← Назад к вопросам

Какие ссылки хранятся в Side Table?

3.0 Senior🔥 71 комментариев
#Управление памятью

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что хранится в Side Table?

Side Table — это вспомогательная структура данных в Swift Runtime (часть реализации системы подсчёта ссылок в Swift), которая хранит дополнительные метаданные для объектов, управляемых через механизм подсчёта ссылок (счётчик ссылок — ARC). Она используется для объектов, которым требуется хранение "слабых" (weak) или "невладеющих" (unowned) ссылок, а также для отслеживания дополнительной информации о состоянии объекта.

Основные типы данных, хранящиеся в Side Table

  1. Weak Reference Count (счётчик слабых ссылок):

    • Хранит количество weak ссылок, указывающих на объект.
    • Когда сильные ссылки на объект исчезают (счётчик сильных ссылок становится нулевым), объект уничтожается, но Side Table может сохраняться для корректной обработки weak-ссылок (они автоматически становятся nil).
    • Пример: при использовании weak var delegate: SomeDelegate?, счётчик weak-ссылок увеличивается.
  2. Unowned Reference Count (счётчик невладеющих ссылок):

    • Отслеживает количество unowned ссылок.
    • В отличие от weak, unowned-ссылки не становятся nil при освобождении объекта, а вызывают ошибку времени выполнения (crash), если объект уже удалён. Side Table помогает отслеживать эти ссылки для корректного управления памятью.
  3. Strong Reference Count Overflow (переполнение счётчика сильных ссылок):

    • Основной счётчик сильных ссылок хранится непосредственно в заголовке объекта (inlinе) для оптимизации.
    • Если количество сильных ссылок превышает ёмкость inline-счётчика (например, очень большое число ссылок), Side Table хранит "лишнюю" часть счётчика (overflow count).
    • На практике такое переполнение случается редко, но Side Table обеспечивает поддержку этого сценария.
  4. Object Lifecycle State (состояние жизненного цикла объекта):

    • Флаги, указывающие на текущее состояние объекта (например, "живой", "в процессе деинициализации", "деинициализирован").
    • Это важно для атомарных операций с ссылками и предотвращения гонок данных в многопоточной среде.
  5. Pointer to the Original Object (указатель на исходный объект):

    • Side Table содержит обратную ссылку на объект, к которому она привязана.
    • Это позволяет weak и unowned ссылкам находить Side Table и проверять, "жив" ли ещё объект.

Как работает Side Table на практике?

Side Table создаётся лениво (по требованию) для объектов, которые в ней нуждаются. Например, при первой слабой ссылке на объект. Объект и его Side Table связаны через указатели: объект хранит указатель на Side Table, а Side Table — на объект. Когда сильные ссылки на объект заканчиваются, объект деинициализируется, но Side Table может оставаться в памяти, пока есть weak-ссылки. Как только все weak-ссылки исчезают, Side Table также освобождается.

Пример кода для иллюстрации

Рассмотрим пример с weak и unowned ссылками:

class MyClass {
    var value: Int
    init(value: Int) { self.value = value }
    deinit { print("MyClass deinitialized") }
}

var strongRef: MyClass? = MyClass(value: 42)  // Сильная ссылка, счетчик strong = 1
weak var weakRef = strongRef                  // Слабая ссылка, создаётся Side Table (если её ещё нет), weak count = 1
unowned var unownedRef = strongRef!           // Невладеющая ссылка, unowned count = 1

print(weakRef?.value) // 42
strongRef = nil       // Сильная ссылка удалена, объект деинициализируется, weakRef становится nil
// unownedRef теперь указывает на освобождённую память — обращение вызовет crash!

В этом примере:

  • При создании weakRef генерируется Side Table (если её не было), где увеличивается weak-счётчик.
  • При установке unownedRef увеличивается unowned-счётчик в той же Side Table.
  • После strongRef = nil объект MyClass уничтожается, но Side Table сохраняется, чтобы обнулить weakRef.

Ключевые термины в контексте Side Table:

  • ARC (Automatic Reference Counting) — автоматический подсчёт ссылок в Swift.
  • Weak Reference — слабая ссылка, не удерживающая объект в памяти.
  • Unowned Reference — невладеющая ссылка, предполагающая, что объект существует во время её использования.
  • Inline Reference Count — счётчик ссылок, хранящийся непосредственно в заголовке объекта для оптимизации.
  • Lazy Allocation — ленивое выделение памяти под Side Table только при необходимости.

Итог

Side Table — это критически важный механизм в Swift для управления weak и unowned ссылками, обработки переполнения счётчиков ссылок и контроля жизненного цикла объектов. Она обеспечивает безопасность памяти и производительность, позволяя основному счётчику ссылок оставаться инлайн в объекте, а дополнительные метаданные хранить отдельно. Понимание Side Table помогает избегать утечек памяти и крешей, связанных с неправильным использованием ссылок.