In this article Brian Goetz lo spiega bene. Fondamentalmente, è correlato al modo in cui funziona il garbage collector. Ha meno lavoro da fare se i nuovi oggetti fanno riferimento a quelli vecchi piuttosto che viceversa.
Estratto dall'articolo legato esempio classi indicati
public class MutableHolder {
private Object value;
public Object getValue() { return value; }
public void setValue(Object o) { value = o; }
}
public class ImmutableHolder {
private final Object value;
public ImmutableHolder(Object o) { value = o; }
public Object getValue() { return value; }
}
Nella maggior parte dei casi, quando un oggetto supporto viene aggiornato per fare riferimento a un oggetto diverso , il nuovo referente è un oggetto giovane. Se aggiorniamo uno MutableHolder
chiamando setValue()
, abbiamo creato una situazione dove un oggetto più vecchio fa riferimento a uno più giovane. D'altra parte, con creando un nuovo oggetto ImmutableHolder
, un oggetto più giovane è che fa riferimento a uno più vecchio.
Quest'ultima situazione, in cui la maggior parte degli oggetti punta a oggetti più vecchi, è molto più delicata su un garbage collector generazionale. Se viene modificato un che vive nella vecchia generazione, tutti gli oggetti nella scheda che contengono lo MutableHolder
devono essere scansionati per i riferimenti vecchio-giovani alla successiva raccolta secondaria.
L'uso di riferimenti mutabili per oggetti container a vita lunga aumenta il lavoro svolto per tracciare riferimenti vecchio-giovani alla data di raccolta .
analisi fuga
Per quanto riguarda la preoccupazione che un sacco di oggetti vengono creati perché si crea un'istanza di un nuovo oggetto ogni volta che è necessario modificare quello esistente, il meccanismo di allocazione degli oggetti è molto migliorata in tutte le JVM.
Dai uno sguardo allo escape analysis (citato anche nell'articolo collegato). Molti oggetti non saranno allocati sull'heap (ma saranno allineati/allocati sullo stack), quindi GC non avrà nulla a che fare con loro (in realtà GC non è a conoscenza dell'esistenza di tali oggetti).
Sebbene non correlato solo all'immutabilità, il meccanismo di analisi di escape può essere utilizzato in modo più efficiente in un contesto immutabile (un esempio è l'oggetto Person
che non viene modificato durante l'invocazione del metodo nei documenti Oracle collegati).
Modern GC è estremamente efficiente con oggetti che "muoiono giovani". Non aver paura di creare e usare oggetti con breve durata; ma fai attenzione a mantenere gli oggetti di riferimento per un tempo più lungo (ad esempio per la memorizzazione nella cache). Il problema non è in realtà sull'immutabilità, più sulla durata della vita. – ZhongYu
Nel tutorial che hai collegato, la frase esatta è _ "overhead decrescente a causa della garbage collection" _. Non c'è una parola "memoria" in essa. Dovresti correggerlo nella tua domanda, perché gli oggetti immutabili potrebbero effettivamente consumare più memoria (perché sei costretto a crearne uno nuovo se vuoi qualcosa cambiato in quello esistente), riducendo tuttavia l'onere complessivo su GC. Maggiori dettagli nella mia risposta qui sotto. –