I valori letterali stringa non vengono archiviati nello stack. Mai. In effetti, nessun oggetto viene memorizzato nello stack.
I valori letterali stringa (o, più precisamente, gli oggetti String che li rappresentano) sono stati storicamente archiviati in un heap chiamato heap "permgen". (Permgen è l'abbreviazione di generazione permanente.)
In circostanze normali, i valori letterali String e gran parte delle altre cose nell'heap permgen sono "permanentemente" raggiungibili e non vengono raccolti in modo indesiderato. (Ad esempio, i valori letterali stringa sono sempre raggiungibili dagli oggetti codice che li utilizzano.) Tuttavia, è possibile configurare una JVM per tentare di trovare e raccogliere classi caricate dinamicamente che non sono più necessarie e ciò potrebbe causare la raccolta di dati obsoleti di stringhe letterali .
CHIARIMENTO # 1 - Non sto dicendo che Permgen non ottiene GC'ed. Lo fa, in genere quando la JVM decide di eseguire un GC completo. Il punto è che i letterali String saranno raggiungibili fintanto che il codice che li usa è raggiungibile, e il codice sarà raggiungibile fintanto che il classloader del codice è raggiungibile, e per i classloader predefiniti, ciò significa "per sempre".
CHIARIMENTO # 2 - In effetti, Java 7 e versioni successive utilizzano l'heap normale per contenere il pool di stringhe. Pertanto, gli oggetti String che rappresentano i valori letterali String e le stringhe interne si trovano effettivamente nell'heap normale. (Vedi la risposta di @ assylias per i dettagli.)
Ma sto ancora cercando di scoprire una linea sottile tra la memorizzazione della stringa letterale e la stringa creata con new
.
Non esiste una "linea sottile". È davvero molto semplice:
String
gli oggetti che rappresentano / corrispondono a stringhe letterali vengono conservati nel pool di stringhe.
String
gli oggetti creati da una String::intern
chiamata vengono conservati nel pool di stringhe.
- Tutti gli altri
String
oggetti NON sono contenuti nel pool di stringhe.
Poi c'è la questione separata di dove è "memorizzato" il pool di stringhe. Prima di Java 7 era l'heap permgen. Da Java 7 in poi è l'heap principale.