Как объекты String хранятся в памяти в Java?

«Как объекты String хранятся в памяти в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Объекты String в Java хранятся в куче (Heap), но для оптимизации используется специальная область — String Pool (пул строк).

Ключевые принципы:

  1. Неизменяемость (Immutability): Строки нельзя изменить после создания. Любая операция, изменяющая строку, создает новый объект.
  2. String Pool: Это хэш-таблица, хранящая уникальные строковые литералы для повторного использования и экономии памяти.
  3. Местоположение: Начиная с Java 7, String Pool перемещен из области PermGen в основную Heap-память и управляется сборщиком мусора.

Как создаются строки:

  • Литерал (String s = "text"): JVM ищет строку в String Pool. Если находит — возвращает ссылку на существующий объект, если нет — создает новый объект в пуле.
  • Конструктор (new String("text")): Всегда создает новый объект в куче, вне зависимости от наличия в пуле.
  • Метод intern(): Помещает строку в пул (или находит существующую) и возвращает на нее ссылку.

Пример, демонстрирующий разницу:

String a = "hello"; // Создается в String Pool
String b = "hello"; // Ссылается на тот же объект из пула
String c = new String("hello"); // Новый объект в Heap
String d = c.intern(); // Ссылается на объект из пула, как a и b

System.out.println(a == b); // true (один объект)
System.out.println(a == c); // false (разные объекты)
System.out.println(a == d); // true

Практический совет: Для конкатенации многих строк используйте StringBuilder или StringBuffer, чтобы избежать создания множества промежуточных строковых объектов.