Строковые литералы не хранятся в стеке. Никогда. Фактически в стеке не хранятся никакие объекты.
Строковые литералы (или , точнее, объекты строк , которые представляют их) являются исторически хранятся в Heap называется «PermGen» куча. (Пермген - сокращение от постоянного поколения.)
В обычных условиях строковые литералы и многое другое в куче permgen доступны «постоянно» и не собираются сборщиком мусора. (Например, строковые литералы всегда доступны из объектов кода, которые их используют.) Однако вы можете настроить JVM для попытки найти и собрать динамически загруженные классы, которые больше не нужны, и это может привести к сборке строковых литералов. .
РАЗЪЯСНЕНИЕ №1 - Я не говорю, что Пермген не получает GC. Обычно это происходит, когда JVM решает запустить полный сборщик мусора. Я хочу сказать, что строковые литералы будут доступны до тех пор, пока доступен код, который их использует, и код будет доступен, пока доступен загрузчик классов, а для загрузчиков классов по умолчанию это означает «навсегда».
УТОЧНЕНИЕ №2. Фактически, Java 7 и более поздние версии используют обычную кучу для хранения пула строк. Таким образом, объекты String, представляющие строковые литералы и внутренние строки, фактически находятся в обычной куче. (Подробнее см. Ответ @ assylias.)
Но я все еще пытаюсь найти тонкую грань между хранением строкового литерала и строкой, созданной с помощью new
.
Нет никакой «тонкой линии». Это действительно очень просто:
String
объекты, которые представляют / соответствуют строковым литералам, хранятся в пуле строк.
String
объекты, созданные String::intern
вызовом, хранятся в пуле строк.
- Все остальные
String
объекты НЕ хранятся в пуле строк.
Затем возникает отдельный вопрос о том, где «хранится» пул строк. До Java 7 это была куча permgen. Начиная с Java 7, это основная куча.