Il conteggio dei riferimenti GC e GC di tracciamento è una proprietà del linguaggio o una proprietà di implementazione?


9

A volte sentiamo "Swift non fa il classico (tracciamento) GC, usa ARC."

Ma non sono sicuro che ci sia qualcosa nella semantica di Swift che richieda il conteggio dei riferimenti. Sembra che si possa costruire il proprio compilatore e runtime Swift per usare GC di traccia.

Quindi, cos'è esattamente "contato come riferimento" su Swift? L'implementazione di Apple o la lingua stessa? Ci sono parti della lingua o della biblioteca che supportano così fortemente ARC che possiamo usare quell'etichetta per la lingua stessa?

Risposte:


9

Swift garantisce che, una volta eliminato l'ultimo riferimento a un oggetto, l'oggetto viene deinizializzato e il deinitcodice viene immediatamente eseguito.

Non è possibile ottenere questo tipo di garanzia tramite GC, almeno non senza sacrificare le prestazioni. I meccanismi GC standard assicurano che il deinitcodice venga eventualmente eseguito, ad esempio al successivo ciclo GC. Per una semantica precisa, è necessario un conteggio dei riferimenti da qualche parte.


3
Ah, quindi la presenza di deinitcome parola chiave e la sua semantica associata sono davvero le cose che mettono il riferimento contando esattamente nella lingua, piuttosto che nel regno dell'implementazione.
Ray Toal,

2
Nulla impedisce a un runtime GCed di verificare la presenza di oggetti non raggiungibili ogni qualvolta viene deallocato. È terribilmente inefficiente.
Raffaello

@Raphael Edited per essere più precisi su questo punto.
chi

3

chi ha risposto alla domanda specifica nel corpo su swift, questa risposta risponde alla domanda più generale nel titolo.

Il conteggio dei riferimenti GC e GC di tracciamento è una proprietà del linguaggio o una proprietà di implementazione?

GC di conteggio dei riferimenti e GC di tracciamento forniscono al programmatore garanzie diverse.

Il conteggio dei riferimenti fornisce determinismo nella posizione nel flusso del programma in cui un oggetto viene distrutto, che può essere importante se l'oggetto possiede scarse risorse che devono essere liberate rapidamente. D'altra parte non può gestire cicli di riferimenti "forti".

Spetta alla specifica di un singolo linguaggio cosa succede se le caratteristiche sono garantite e quindi quali scelte sono disponibili per un'implementazione conforme.


4
È anche possibile combinare refcount e GC. Quindi il linguaggio può documentare che gli oggetti hanno il loro distruttore eseguito non appena non sono referenziati (implicando un nuovo conteggio in una forma o nell'altra) e che i cicli di riferimento saranno infine distrutti (implicando una qualche forma di GC). In alternativa, l'implementazione potrebbe farlo mentre il linguaggio non garantisce quando vengono eseguiti i distruttori (IIRC è il caso di Python e della sua implementazione di riferimento), nel qual caso sarebbe una proprietà di implementazione.
Gilles 'SO- smetti di essere malvagio' il

1

Puoi prendere la lingua conosciuta come Swift e rinominarla in "Swift con ARC". È quindi possibile creare un nuovo linguaggio chiamato "Swift con GC" con esattamente la stessa sintassi, ma con meno garanzie su quando gli oggetti vengono deallocati.

In Swift con ARC, una volta che il conteggio dei riferimenti è 0, l'oggetto andrà. Con Garbage Collection, purché si abbia un riferimento debole, è possibile assegnare quel riferimento debole a un riferimento forte per "recuperare" l'oggetto. (In Swift, una volta che il conteggio dei riferimenti è 0, i riferimenti deboli sono nulli); questa è una grande differenza.

E ovviamente Swift con ARC garantisce che l'uccisione dell'ultimo conteggio di riferimento trasferirà immediatamente l'oggetto. Ad esempio, potresti avere una classe FileWriter, in cui non puoi avere due istanze che scrivono nello stesso file esistente contemporaneamente. In Swift con ARC potresti dire oldWriter = nil; newWriter = FileWriter (...) e sapresti che il nuovo FileWriter viene creato solo dopo che quello vecchio è stato eliminato (a meno che tu non abbia tenuto un altro riferimento in giro); in Swift con GC questo non funzionerebbe.

Un'altra differenza è che in "Swift con ARC", gli oggetti a cui si fa riferimento solo attraverso cicli di riferimento forti, ma che in realtà non sono raggiungibili, non vengono garantiti .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.