Подходят ли интернированные константы для GC?

Цитирование этой страницы:

Сколько объектов будет иметь право на GC здесь?

String s = "hello";
Character ch1 = 1;
Character ch2 = 1;
ch1 = null;
s = null; 

Я считаю, что ответ 1.

Я хотел бы понять, как это работает в Java 6.

Мое понимание на данный момент:

Строка идет в бассейн. Позже о нем не упоминается. Итак, согласно этому ответу (я не понимаю эту часть насчет загрузчика классов, можете пояснить?), пул строк скорее всего не будет собираться мусором...

Хорошо, Персонажи. В Java существует эта оптимизация, которая приведет к тому, что ch1 и ch2 будут указывать на один и тот же объект. Итак, эти маленькие Персонажи тоже собираются в какой-то бассейн. Но, несмотря на то, что ch1 является null, мы по-прежнему можем получить доступ к 1 по ссылке ch2.

Итак, мой ответ на данный момент будет 0.

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


person Adam Stelmaszczyk    schedule 03.12.2014    source источник
comment
Учитывая предложение перед цитируемой частью: «В отличие от пула строк для литералов, этот кеш не влияет на GC» и то, что автор хотел подчеркнуть, кажется, что они просто забыли чтобы поместить в код оператор ch2 = null;. Они хотели указать, что пул Character не обязательно поддерживает объект в рабочем состоянии (в отличие от пула String), но сохранение ссылки на него в ch2 привело к уничтожению этой точки. Однако, как деталь реализации, пул эталонной реализации действительно поддерживает объекты Character с помощью переменной static. Дело закрыто… или… нет?   -  person Holger    schedule 08.06.2020
comment
Как подробно описано в Может ли java завершить объект, когда он все еще находится в области видимости?, локальные переменные в любом случае не обязательно сохраняют свои референты. . Как правило, сборщиком мусора может стать каждый объект, если приложение этого не заметит. Таким образом, ни одному пулу не нужно поддерживать объекты в рабочем состоянии. Кроме того, в наиболее распространенных реализациях String представляет собой оболочку вокруг объекта массива, другими словами, состоит из двух объектов. Таким образом, формально правильным ответом будет 0, 1, 2 или 3 объекта, в зависимости от реализации; мы просто не знаем и не должны знать...   -  person Holger    schedule 08.06.2020


Ответы (1)


Ваш ответ «ничего не собирается» верен, по крайней мере, до тех пор, пока класс, определяющий строку, находится поблизости.

"hello" — это строковый литерал, и класс, в котором он появляется, ссылается на него. Пока класс достижим, литерал остается.

Класс тоже может быть GC'd. Но каждый класс ссылается на свой загрузчик классов и ссылается на него. Обычно вы не заботитесь о загрузчиках классов, так как вы используете загрузчик по умолчанию, и он (и все ваши классы) остается до конца.

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

person maaartinus    schedule 04.12.2014