2015-09-25 17 views
5

Non riesco a capire l'implementazione di alcune operazioni per le sequenze immutabili di Scala. Userò questo come esempio:Come funziona la gestione della memoria per le collezioni Scala?

def example: List[Int] = { 
    val list0 = List.range(1,10) 

    list0.tail 
} 

Una volta terminata la funzione, l'elenco0 è ora fuori portata. La testa di list0 sarebbe stata rimossa dalla memoria, o sarebbe list0 rimanere la stessa finché l'intera lista non viene raccolta?

+0

Scala usa il garbage collector come Java. Quindi questa lista verrà rimossa dalla memoria quando gc verrà lanciato di nuovo da jvm e si renderà conto che questo oggetto può essere raccolto. – Everv0id

risposta

6

Nel tuo esempio, la testa di list0 sarà lasciato al garbage collector di raccogliere, come nulla farà riferimento esso. Gli articoli rimanenti (la coda), tuttavia, continueranno ad esistere all'uscita dalla funzione (a condizione che il risultato della chiamata sia assegnato a qualcosa).

Ogni cella di un elenco mantiene un riferimento alla cella successiva nell'elenco (o a Nil), ma non viceversa.

+0

Non ritiene il fatto che la testa ha un riferimento a un altro nodo evitare che venga garbage collection? Tale riferimento viene rimosso una volta fuori dal campo di applicazione? – user3599828

+6

No, il garbage collector non si preoccupa se un elemento ha le proprie riferimenti ad altre cose; si preoccupa solo che l'oggetto non abbia nient'altro che si riferisca a * it *. Finché ciò è vero, l'elemento è un candidato per la garbage collection. – kes

1

Si crea un totale di 12 (possibili) entità

  1. list0 - Un elenco contenente da 1 a 10.
  2. I 10 singoli elementi nell'intervallo da 1 a 10. Questi potrebbero essere internati, ma questa è una discussione diversa.
  3. Il valore restituito, list0.tail, che contiene gli elementi 2-10.

Ecco il grafico di memoria concettuale prima dell'ultima parentesi graffa, ecco i riferimenti

  Somewhere on JVM Stack list0(head)->1->2 ... ->10 
               | 
Top of JVM Stack, contains returnList with head->| 

Quando la funzione è fatto, il riferimento list0 sarà spuntato fuori e potranno beneficiare di raccolta dei rifiuti. Poiché list0 è l'unica cosa che fa riferimento a 1, 1 è anche un gioco equo per la raccolta dei rifiuti.

Gli elementi 2-10 e la lista restituita che li contiene rimarranno nell'heap poiché chi fa riferimento a example è ancora raggiungibile dal codice in esecuzione.

Spero che questo aiuti.