In Swift, value types (such as struct, enum, and tuple) are usually allocated on the stack, whereas reference types (such as class) are allocated on the heap.
Stack allocation is fast, automatic, and used for storing local variables with a short lifetime. Heap allocation requires additional overhead and is used for objects with an indeterminate lifetime or size.
Example:
struct Point { var x: Int; var y: Int } let p1 = Point(x: 2, y: 3) // On the stack class Node { var value: Int; init(value: Int) { self.value = value } } let n1 = Node(value: 5) // In the heap
Details:
structs in the heap if they are nested within a class or placed in a collection.Performance: Stack allocation is faster as it does not require dealing with heap memory and managing object lifetimes.
Do all structures (struct) always reside exclusively on the stack?
Answer:
No! While structures are value types and are often placed on the stack, the compiler may store them in the heap if they are part of a class, an array, a dictionary, or used as captured values in closures. For instance:
class Box { var point: Point init(point: Point) { self.point = point } } let box = Box(point: Point(x: 1, y: 2))
Here, the instance of Point will be stored in the heap, as it belongs to the class Box.
Story
A developer tried to optimize the performance of structures, believing that large structures would always be in the stack, and did not account for the fact that collections (Array, Dictionary) use heap allocation, leading to unexpected memory usage increases in the project.
Story
In the project, they did not consider that closures capture the value of a structure, which ends up in the heap, affecting the object's life. This increased the lifetime of variables and led to memory leaks as they expected automatic release when going out of scope.
Story
Using arrays of heavy structures without understanding copy-on-write led to unexpectedly expensive copy operations due to passing collections between threads, reducing performance and causing UI delays.