Вопрос-ответ

Are static fields open for garbage collection?

Открыты ли статические поля для сборки мусора?

Дан гипотетический служебный класс, который используется только при настройке программы:

class MyUtils {
private static MyObject myObject = new MyObject();
/*package*/static boolean doStuff(Params... params) {
// do stuff with myObject and params...
}
}

будет ли MyObject собираться мусором, когда он больше не используется, или он останется на весь срок службы программы?

Переведено автоматически
Ответ 1

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

Ознакомьтесь с разделом 12.7 JLS " Выгрузка классов и интерфейсов"


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


Ответ 2

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

Ответ 3

MyObject - это ссылка, а не объект. Объект автоматически собирается мусором, когда на него нет ссылок, потому что он недоступен.

Таким образом, объект, стоящий за статической ссылкой "MyObject", также может быть собран мусором, если вы разыменуете его с помощью

myObject = null;

и других ссылок на этот объект нет.

Однако статические ссылки и переменные остаются на протяжении всего срока службы вашей программы.

Ответ 4

Если вы хотите, чтобы временный объект использовался для статической инициализации, а затем удалялся, вы можете использовать блок статического инициализатора, например

class MyUtils {
static
{
MyObject myObject = new MyObject();
doStuff(myObject, params);
}

static boolean doStuff(MyObject myObject, Params... params) {
// do stuff with myObject and params...
}
}

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

java