ProgrammazioneSviluppatore iOS

Как работает stack allocation и heap allocation в Swift? В каких случаях объекты размещаются на стеке или куче, как это влияет на производительность и жизненный цикл объектов?

Supera i colloqui con l'assistente IA Hintsage

Risposta

In Swift, i tipi di valore (value types), come struct, enum e tuple, vengono solitamente allocati nello stack, mentre i tipi di riferimento (reference types), come class, sono allocati nell'heap.

Stack allocation è veloce, automatica e utilizzata per memorizzare variabili locali con una vita breve. Heap allocation richiede costi aggiuntivi ed è utilizzata per oggetti con una durata di vita indefinita o una dimensione maggiore.

Esempio:

struct Point { var x: Int; var y: Int } let p1 = Point(x: 2, y: 3) // Nello stack class Node { var value: Int; init(value: Int) { self.value = value } } let n1 = Node(value: 5) // Nell'heap

Nuggets:

  • Il compilatore/ottimizzatore Swift può allocare anche le struct nell'heap se sono interne a una classe o se sono memorizzate in una collezione.
  • I value types vengono copiati quando vengono passati, il che porta generalmente a una copia nello stack, ma Swift implementa copy-on-write per le collezioni.
  • L'heap allocation richiede il controllo della durata di vita degli oggetti (ARC). Gli oggetti allocati nello stack vengono distrutti automaticamente al di fuori del loro scope.

Prestazioni: L'allocazione nello stack è più veloce poiché non richiede operazioni di gestione della memoria nell'heap e controllo della vita degli oggetti.

Domanda trabocchetto

Tutte le struct (struct) sono sempre allocate esclusivamente nello stack?

Risposta:
No! Anche se le struct sono value types e sono spesso allocate nello stack, il compilatore può allocarle nell'heap se si trovano all'interno di un oggetto classe, di un array, di un dizionario o se usate come captured value in una closure. Ad esempio:

class Box { var point: Point init(point: Point) { self.point = point } } let box = Box(point: Point(x: 1, y: 2))

Qui l'istanza Point sarà memorizzata nell'heap poiché appartiene alla classe Box.

Esempi di errori reali a causa della mancanza di conoscenze sui dettagli dell'argomento


Storia

Un sviluppatore stava tentando di ottimizzare le prestazioni delle struct, pensando che le struct grandi sarebbero sempre state allocate nello stack, senza considerare che le collezioni (Array, Dictionary) utilizzano l'allocazione nell'heap, portando a un inatteso aumento dei costi di memoria nel progetto.


Storia

Nel progetto non si considerava che la closure cattura il valore della struct, che finisce nell'heap, influenzando il tempo di vita dell'oggetto. Ciò ha aumentato il tempo di vita delle variabili e ha portato a perdite di memoria, poiché ci si aspettava un rilascio automatico al di fuori dello scope.


Storia

L'uso di array di struct pesanti senza comprendere copy-on-write ha portato a costose operazioni di copia a causa della trasmissione delle collezioni tra i thread, riducendo le prestazioni e causando ritardi nell'interfaccia utente.