2013-05-31 2 views
1

Когда мы ставим строку, мы убеждаемся, что все использования этой строки относятся к одному экземпляру.Интернирование строки

Предполагаю, что основной объект строки находится в куче.

Однако, где переменная-референт, хранящаяся в памяти?

Имеет ли он то же поведение, что и static - где ссылка хранится в permgen и делает экземпляр строки доступным для gc только после выхода загрузчика (и приложения) класса?

+1

Статические ссылки не сохраняются в perm gen. – SimonC

+0

Не знаете, что вы подразумеваете под «referring variable». Существует своего рода каталог интернированных строк, но это скрыто, и вам не нужно беспокоиться об этом. Любая ссылка, которую вы имеете на интернированную строку, может иметь любой класс хранения, который вы хотите. –

+1

@SimonC - на самом деле, статические ссылки могут быть в permgen, потому что статический фрейм, который их удерживает, может быть объектом пермг. (Конечно, * имеет смысл * для того, чтобы статический фрейм был в пермгене, потому что его время жизни привязано к загрузчику классов, который загружал класс!). Именно объекты, к которым относятся статические переменные, обычно не относятся. –

ответ

5

До JDK 6 Внутренние строки хранятся в пуле памяти в месте под названием Постоянное поколение, которое является областью JVM, зарезервированной для объектов, не являющихся пользователями, такими как Классы, Методы и другие внутренние Объекты JVM. Размер этой области ограничен и обычно намного меньше кучи.

Из JDK 7 интернированные строки больше не выделяются в постоянном поколении кучи Java, а вместо этого выделяются в основной части кучи Java (так называемые молодые и старые поколения) вместе с другими объектами созданный приложением. Это изменение приведет к большему количеству данных, находящихся в основной куче Java, и меньше данных в постоянном поколении, и, следовательно, может потребоваться корректировка размеров кучи. Из-за этого большинства приложений будут наблюдаться лишь относительно небольшие различия в использовании кучи, но более крупные приложения, загружающие многие классы или интенсивно использующие метод String.intern(), будут видеть более значительные различия.

Подробное объяснение этого можно найти на этом answer.

2

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

Не совсем. Когда вы сделаете это:

String s2 = s1.intern(); 

то, что вы делаете, гарантируя, что s2 относится к String в строке бассейна. Это не влияет на значение в s1 или на любые другие ссылки или переменные String. Если вы хотите, чтобы другие копии строки были интернированы, вам нужно сделать это явно ... или назначить интернированные ссылки на строки для соответствующих переменных.

Я бы предположил, что основной объект строки находится в куче.

Это верно. Это может быть в куче «permgen» или обычной куче, в зависимости от версии Java, которую вы используете. Но это всегда «в куче».

Однако, где переменная-референт хранится в памяти?

«со ссылкой переменной» ... то есть один, который содержит ссылку, что вы получили от вызова intern() ... ничем не отличается от любой другой переменной.Это может быть

  • локальная переменная или параметр (удерживается в кадре стека),
  • поле экземпляра (проводится в обычном объекте кучи),
  • статическое поле (проводится в объекте PermGen кучи) ... или даже
  • jstring переменных или аналогичный в JNI коде (проводится «где-то еще».)

в самом деле, типичный JVM использует секретный хэш-таблицу для хранения ссылок на интернированные строки, и он использует слабое повторение JVM чтобы гарантировать, что интернированные строки могут быть собраны в мусор, если ничто другое не использует их.

Имеет ли он то же поведение, что и статический, - где ссылка хранится в permgen и делает экземпляр строки доступным для gc только после выхода загрузчика (и приложения)?

Обычно нет ... см. Выше.

На большинстве платформ Java интернированные строки могут быть собраны как у других Строков. Если интернированные строки хранятся в пространстве «пермг», для сбора объекта может потребоваться больше времени, потому что «пермг» собирается нечасто. Однако время жизни интернированной строки не привязано к времени жизни загрузчика классов и т. Д.

+0

Строка 'static' не обязательно является строковым литералом. Оппозиция кажется путаной и в этом вопросе. –

+0

@TimBender - правильно ... и он хорошо может быть. Но я не понимаю этого впечатления от того, что он написал. –