В Swift типы-значения (значимые типы), такие как struct, enum и tuple, обычно размещаются на стеке, тогда как типы-ссылки (reference types), такие как class, — в куче (heap).
Stack allocation быстра, автоматическая и используется для хранения локальных переменных с коротким временем жизни. Heap allocation требует дополнительных затрат и используется для объектов с неопределённым временем жизни или размером.
Пример:
struct Point { var x: Int; var y: Int } let p1 = Point(x: 2, y: 3) // На стеке class Node { var value: Int; init(value: Int) { self.value = value } } let n1 = Node(value: 5) // В куче
Нюансы:
Производительность: Stack allocation быстрее, так как не требует работы с памятью в куче и управления временем жизни объектов.
Все ли структуры (struct) всегда размещаются исключительно на стеке?
Ответ:
Нет! Хотя структуры — value types и их часто размещают на стеке, компилятор может хранить их в куче, если они находятся внутри объекта класса, массива, словаря или используются в качестве captured value в closure. Например:
class Box { var point: Point init(point: Point) { self.point = point } } let box = Box(point: Point(x: 1, y: 2))
Здесь экземпляр Point будет храниться в куче, так как принадлежит классу Box.
История
Разработчик пытался оптимизировать производительность структур, считая, что крупные структуры всегда будут лежать на стеке, и не учитывал, что коллекции (Array, Dictionary) используют heap allocation, что привело к неожиданному увеличению расхода памяти в проекте.
История
В проекте не учитывали, что closure захватывает значение структуры, которое оказывается в куче, влияя на время жизни объекта. Это увеличило время жизни переменных и привело к утечкам памяти, так как ожидали автоматического освобождения при выходе из области видимости.
История
Использование массивов тяжелых структур без понимания copy-on-write привело к неожиданно дорогим операциям копирования из-за передачи коллекций между потоками, снижая производительность и вызывая задержки в UI.