Когда мы ставим строку, мы убеждаемся, что все использования этой строки относятся к одному экземпляру.
Не совсем. Когда вы сделаете это:
String s2 = s1.intern();
то, что вы делаете, гарантируя, что s2
относится к String
в строке бассейна. Это не влияет на значение в s1
или на любые другие ссылки или переменные String
. Если вы хотите, чтобы другие копии строки были интернированы, вам нужно сделать это явно ... или назначить интернированные ссылки на строки для соответствующих переменных.
Я бы предположил, что основной объект строки находится в куче.
Это верно. Это может быть в куче «permgen» или обычной куче, в зависимости от версии Java, которую вы используете. Но это всегда «в куче».
Однако, где переменная-референт хранится в памяти?
«со ссылкой переменной» ... то есть один, который содержит ссылку, что вы получили от вызова intern()
... ничем не отличается от любой другой переменной.Это может быть
- локальная переменная или параметр (удерживается в кадре стека),
- поле экземпляра (проводится в обычном объекте кучи),
- статическое поле (проводится в объекте PermGen кучи) ... или даже
jstring
переменных или аналогичный в JNI коде (проводится «где-то еще».)
в самом деле, типичный JVM использует секретный хэш-таблицу для хранения ссылок на интернированные строки, и он использует слабое повторение JVM чтобы гарантировать, что интернированные строки могут быть собраны в мусор, если ничто другое не использует их.
Имеет ли он то же поведение, что и статический, - где ссылка хранится в permgen и делает экземпляр строки доступным для gc только после выхода загрузчика (и приложения)?
Обычно нет ... см. Выше.
На большинстве платформ Java интернированные строки могут быть собраны как у других Строков. Если интернированные строки хранятся в пространстве «пермг», для сбора объекта может потребоваться больше времени, потому что «пермг» собирается нечасто. Однако время жизни интернированной строки не привязано к времени жизни загрузчика классов и т. Д.
Статические ссылки не сохраняются в perm gen. – SimonC
Не знаете, что вы подразумеваете под «referring variable». Существует своего рода каталог интернированных строк, но это скрыто, и вам не нужно беспокоиться об этом. Любая ссылка, которую вы имеете на интернированную строку, может иметь любой класс хранения, который вы хотите. –
@SimonC - на самом деле, статические ссылки могут быть в permgen, потому что статический фрейм, который их удерживает, может быть объектом пермг. (Конечно, * имеет смысл * для того, чтобы статический фрейм был в пермгене, потому что его время жизни привязано к загрузчику классов, который загружал класс!). Именно объекты, к которым относятся статические переменные, обычно не относятся. –