2013-01-07 10 views
9

Conosco il motivo per cui JVM GC ama gli oggetti di breve durata perché possono essere raccolti in GC minori. Ma perché JVM GC ama gli oggetti immutabili?Perché gli oggetti immutabili sono amati dal GC di JVM?

MODIFICA: Charlie Hunt dice che GC ama gli oggetti immutabili nel suo presentation.

Grazie

+0

Chi dice che JVM GC ama gli oggetti immutabili? – lichengwu

+0

Grazie, @lichengwu, ho modificato la domanda aggiungendo la fonte. – Jacky

risposta

7

Se il GC può sapere che un oggetto non contiene riferimenti a oggetti gen0, può essere ignorato durante l'esecuzione di una raccolta gen0. Allo stesso modo, se un oggetto non contiene alcun riferimento a nessun oggetto gen0 o gen1, può essere ignorato quando si esegue una raccolta gen1. Più oggetti possono essere ignorati durante una raccolta, più veloce sarà quella raccolta.

Se un oggetto sopravvive a un GC gen0, può essere certo che qualsiasi oggetto gen0 a cui è stato assegnato un riferimento sarà stato promosso a gen1; allo stesso modo se un oggetto che non contiene riferimenti gen0 sopravvive a un GC gen1, qualsiasi riferimento a gen1 contenuto in esso sarà stato promosso a gen2. Pertanto, una volta che un oggetto è stato esaminato durante una raccolta gen0, non è necessario esaminarlo nuovamente fino alla prossima raccolta gen1, , a meno che non venga modificata. Allo stesso modo, un oggetto esaminato durante una raccolta gen1 non deve essere esaminato fino alla prossima collezione gen2 a meno che non venga modificato.

Sapere se gli oggetti sono stati modificati è un argomento delicato, ma il punto chiave è che è molto vantaggioso per il GC se gli oggetti non lo sono stati.

+0

Grazie, @supercat. Ho delle domande: a) "ignorare" significa che non rintraccia ulteriormente l'oggetto? b) Che cos'è gen0, gen1 e gen2? Vuoi dire una generazione giovane e vecchia? c) GC sa se gli oggetti sono stati modificati? – Jacky

+1

@Jacky: con "ignora" intendo davvero "non intendo più tracciare". Principalmente uso .net quale generazione di numeri 0-2; Penso che le implementazioni Java abbiano più di una generazione "giovane" e "vecchia", ma non conosco i dettagli. Affinché il GC possa sfruttare le generazioni nella fase di "mark", deve sapere quali oggetti possono essere stati modificati dall'ultimo GC per ogni generazione. I meccanismi per questo sono piuttosto complicati. Se esistessero mezzi speciali per dichiarare oggetti immutabili che richiedevano che il contenuto fosse specificato prima che i riferimenti potessero essere ... – supercat

+2

... passati dall'ambito di esecuzione corrente, tali oggetti non avrebbero bisogno di avere i meccanismi associati al tracciamento se erano cambiati (dato che semplicemente non sarebbero cambiati); in alternativa, su qualsiasi sistema che supporti meccanismi di memoria virtuale abbastanza sofisticati per tracciare le modifiche agli oggetti mutabili (e anche molti con meccanismi VM che sono molto più limitati), quegli stessi meccanismi potrebbero essere usati per garantire che gli oggetti immutabili non possano essere cambiati dal codice "canaglia". – supercat

2

Grazie per la link..found è bello :)

dalla presentazione: GC ama piccoli oggetti immutabili e oggetti vissuti brevi.

Edit:

Smaller oggetti hanno breve occupazione di memoria che significa che dopo la raccolta non ci sarà molto di sovraccarico sulla compattazione di memoria (Memory compattazione è lento per il grande oggetto che lasciano buchi di memoria più grandi dopo che vengono recuperati da GC). E gli oggetti di breve durata sono anche buoni quando vengono raccolti in piccoli cicli GC.

+0

È probabile che un oggetto di grandi dimensioni venga promosso direttamente alla vecchia generazione se non può entrare nell'area di sopravvivenza durante la gc minore. Nel peggiore dei casi, può essere promosso direttamente nella vecchia generazione quando viene creato se non può entrare nello spazio libero della giovane generazione. – Jacky

+0

Gli oggetti immutabili hanno molti vantaggi. Penso che GC possa facilmente trovare tutti gli oggetti immutabili durante la tracciatura. Non ho capito come può ridurre il sovraccarico di prendersi cura di loro. Credo che ci siano alcuni motivi per cui Hunt ha detto questo. – Jacky

+0

Sì, avere un oggetto immutabile più piccolo è il caso ideale per prestazioni ottimali, ma non sottolinea mai che GC favorisce SOLO oggetti immutabili. –

2

Ho trovato la risposta da article di Brian Goetz.

Nella maggior parte dei casi, quando un oggetto titolare viene aggiornato per fare riferimento a un oggetto diverso, il nuovo referente è un oggetto giovane. Se aggiorniamo un MutableHolder chiamando setValue(), abbiamo creato una situazione in cui un oggetto precedente fa riferimento a uno più giovane. D'altra parte, creando invece un nuovo oggetto ImmutableHolder, un oggetto più giovane fa riferimento a uno più vecchio. Quest'ultima situazione, in cui la maggior parte degli oggetti puntano a oggetti più vecchi, è molto più delicata su un garbage collector generazionale. Se un MutableHolder che vive nella vecchia generazione è mutato, tutti gli oggetti sulla carta che contengono il MutableHolder devono essere scansionati per riferimenti vecchio-giovani alla prossima raccolta minore. L'uso di riferimenti mutabili per oggetti container a vita lunga aumenta il lavoro svolto per tracciare riferimenti vecchi-giovani al momento della raccolta.

+0

Mi chiedo se qualsiasi framework GC degno di nota abbia un heap separato per oggetti mutevoli e immutabili, a condizione che gli heap immutabili non abbiano bisogno di tabelle di carte. In effetti, se si cercasse un framework compatto, penserei che si possa ottenere prestazioni decenti senza tabelle di carte se gli oggetti mutabili gen1/gen2 sono stati scansionati (ma non spostati) su ogni collezione ma non quelli immutabili no. – supercat

Problemi correlati