Что делать, если размер пула строк превышает?

В Java,

Строковые литералы в String Constant Pool не собирают мусор, поскольку они ссылаются на таблицу ссылок, которая создается экземпляром среды выполнения для оптимизации пространства.

Если размер литерального пула строк больше, Поскольку каждый строковый литерал в String имеет ссылку, поэтому он не будет иметь права на GC. как это обрабатывается JVM?

Ответ 1

Существует длинное обсуждение реальных примеров кода в JavaRanch.

Общий вывод следующий:

  • Если строка добавлена ​​в постоянный пул в RUNTIME с использованием String.intern(), то может быть мусором, собранным после того, как он больше не используется. Скорее всего, пул строк хранит только мягкие ссылки на добавленные строки, что позволяет мусору их собирать (не может быть уверен, потому что String.intern() является нативным методом).
  • Если строка - постоянная времени COMPILE, она добавляется в пул констант соответствующего класса. Следовательно, это может быть сбор мусора только после того, как класс выгружен.

Ответ на ваш вопрос: единственный способ получить OutOfMemoryError из-за String constants - загрузить много классов со многими строковыми литералами, вычисленными во время компиляции. Тогда вы можете в конечном итоге превысить максимальный размер пространства PermGen. Но это произойдет во время загрузки классов в память (например, запустите приложение, разверните проект на WebServer, динамически загрузите новую библиотеку и т.д.).

Ответ 2

Строковые литералы могут быть собраны, когда они больше не нужны. Обычно это не проблема, если они появляются в классах, потому что есть другие ограничения, которые вы, вероятно, достигнете, если попытаетесь загрузить множество классов, например. Максимальный пермский генерал

В общем, разработчики достаточно умны, чтобы не использовать пул строковых литералов и вместо этого использовать базы данных или файл для загрузки основной части своих данных, если его нетривиальный размер.

Вы можете ввести проблему, если многократно используете String.intern(), пытаясь оптимизировать пространство вашей системы. String.intern() не является бесплатным и становится все дороже, если вы добавляете в него большое количество (миллионов) строк. Если это проблема с производительностью, она должна быть достаточно очевидной для разработчика, когда она есть.