Ответ
Интернирование строк — это механизм в Java, при котором все строковые литералы и строки, явно добавленные в пул, хранятся в специальной области heap памяти, называемой String Pool (пул строк). Его цель — экономия памяти и повышение производительности за счёт повторного использования неизменяемых (immutable) строковых объектов.
Как это работает:
- При создании строкового литерала (
"text") JVM сначала ищет строку с таким же значением в пуле. - Если строка найдена, возвращается ссылка на существующий объект. Если нет — создаётся новый объект в пуле.
- Строки, созданные через оператор
new String(...), по умолчанию не интернируются и размещаются в обычной heap-памяти.
Пример:
String s1 = "hello"; // Литерал -> попадает в пул
String s2 = "hello"; // Находит "hello" в пуле -> s1 == s2 (true)
String s3 = new String("hello"); // Создаётся новый объект вне пула
String s4 = s3.intern(); // Явное интернирование, s4 теперь ссылается на объект из пула
System.out.println(s1 == s2); // true (одна ссылка)
System.out.println(s1 == s3); // false (разные объекты)
System.out.println(s1 == s4); // true (s4 после intern() ссылается на объект из пула)
Метод String.intern():
- Помещает строку в пул, если её там ещё нет, и возвращает ссылку на строку из пула.
- Если строка уже есть в пуле, возвращает существующую ссылку.
Важные особенности:
- Пул строк находится в Heap (ранее — в Permanent Generation, до Java 7).
- Строки в пуле могут быть удалены сборщиком мусора, если на них нет ссылок.
- Использовать
intern()стоит с осторожностью, так как неконтролируемое наполнение пула может привести к излишнему потреблению памяти (утечке). Оптимально использовать для долгоживущих строк с высоким шансом повторения.
Ответ 18+ 🔞
А, интернирование строк! Ну это ж классика, блядь, как "Муму" у Тургенева, только про байты и хеш-коды, а не про собак. Сейчас объясню на пальцах, чтобы даже мартышлюшка с ушами поняла.
Представь себе, что строка в Java — это как Герасим, здоровый мужик, но немой. Он может сказать только "Муму". И таких Герасимов, которые мычат одно и то же, может быть дохуя. Зачем плодить сущностей, блядь? Вот для этого и придумали String Pool — этакий общий сарай, куда складывают каждого уникального Герасима по одному разу.
Как эта магия работает, ёпта:
- Пишешь ты
String s1 = "hello";— JVM, хитрая жопа, лезет в этот сарай-пул, смотрит: а есть у нас уже Герасим, который мычит "hello"? Нету? Ну, блядь, создаём нового и в сарай его. Есть? О, сука, отлично! Возвращаем тебе ссылку на того, который уже там стоит, сэкономили память, молодцы. - А вот если ты через
new String("hello")создаёшь — это как взять и построить Герасима-дублера прямо посреди поля. Он внешне такой же, мычит так же, но живёт в другом месте. И ссылки у вас будут разные, пиздец.
Смотри, как это в коде выглядит, тут всё честно:
String s1 = "hello"; // Сарай (пул). Герасим №1.
String s2 = "hello"; // Идём в сарай, находим того же Герасима №1. s1 и s2 — одно лицо!
String s3 = new String("hello"); // А это новый Герасим №2, но на вольных хлебах, вне сарая.
String s4 = s3.intern(); // Говорим Герасиму №2: "Иди в сарай, блядь!" Он идёт, видит, что его клон уже там, и начинает тыкать пальцем в того, первого.
System.out.println(s1 == s2); // true (Оба пальцем тыкают в одного и того же Герасима в сарае)
System.out.println(s1 == s3); // false (Один в сарае, другой по полю гуляет — разные объекты!)
System.out.println(s1 == s4); // true (s4 после intern() тоже тыкает в сарайного Герасима)
Метод intern() — это, блядь, как команда "В сарай!"
Крикнул intern() — и строка либо залетает в пул (если её там не было), либо, если её дубль уже там сидит, просто начинает на него ссылаться. Всё, чтобы не плодить одинаковых мычащих Герасимов по всему heap'у.
А теперь, внимание, ебать мои старые костыли, важные детали:
- Пул строк сейчас живёт в обычной куче (Heap), а не где-то на небесах. Раньше, до Java 7, его в Permanent Generation пихали, но там тесно стало.
- Да-да, Герасимов из сарая могут выкинуть, если на них никто не тычет пальцем. Сборщик мусора и там рулит.
- С
intern()надо как с ножом — осторожно, ёпта. Начать бездумно пихать в пул всё подряд — это гарантированно получить овердохуища одинаковых строк и утечку памяти. Используй это дело только для тех строк, которые реально будут жить долго и встречаться чаще, чем пидары на халявную раздачу. Иначе сарай лопнет, и будет тебе пиздец, а не оптимизация.
Вот и вся философия. Литералы — сразу в сарай. new — гуляй, Вася. Захотел оптимизации — кричи intern() и отправляй в сарай. Главное — не переборщить, а то вместо быстрой программы получишь памятник Герасиму, который всех замусорил.