Открыты ли статические поля для сборки мусора? - PullRequest
83 голосов
/ 17 января 2009

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

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

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

Ответы [ 6 ]

105 голосов
/ 17 января 2009

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

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

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

47 голосов
/ 17 января 2009

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

13 голосов
/ 17 января 2009

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

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

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

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

9 голосов
/ 11 июля 2014

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

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

myObject = null;

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

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

6 голосов
/ 17 января 2009

Я думаю, это отвечает на ваш вопрос - в основном, если только класс не поступает из специального загрузчика классов и не выгружает класс.

0 голосов
/ 03 мая 2018

Ключевым моментом здесь является сборка мусора экземпляров Class, т.е. объектов. Экземпляр ClassLoader, по сути, является объектом. Поэтому, если объект Classloader не является сборщиком мусора, любые ссылки на них, хранящиеся в куче (то есть статические вещи), почти никогда не будут собираться мусором. Исключение составляет строковый пул.

Так что, прежде чем вдруг решите сделать private static MyGiantClass myGiantObject = new MyGiantClass() Подумайте дважды, как я выучил трудный путь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...