Является ли настройка объектов Java на null больше чем-либо?

Я просматривал некоторые старые книги и нашел копию "Практической Java" Питера Хаггера. В разделе производительности есть рекомендация установить ссылки на объекты null, когда они больше не нужны.

В Java, привязывает ли объект ссылки к null эффективность работы или сборку мусора? Если да, то в каких случаях это проблема? Контейнерные классы? Состав объекта? Анонимные внутренние классы?

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

Ответ 1

Это немного зависит от того, когда вы решили обнулить ссылку.

Если у вас есть цепочка объектов A- > B- > C, то, как только A окажется недоступным, A, B и C будут иметь право на сбор мусора (предполагая, что ничто иное не относится ни к B, ни к C). Нет необходимости и никогда не нужно было явно указывать ссылки A- > B или B- > C на нуль, например.

Кроме того, большую часть времени проблема не возникает, потому что на самом деле вы имеете дело с объектами в коллекциях. Обычно вы всегда должны думать об удалении объектов из списков, карт и т.д., Вызывая метод appropiate remove().

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

{
  BigObject obj = ...
  doSomethingWith(obj);
  obj = null;             <-- explicitly set to null
  doSomethingElse();
}

Обоснование здесь состояло в том, что поскольку obj все еще находится в области видимости, то без явного обнуления ссылки он не становится сборщиком мусора до тех пор, пока метод doSomethingElse() не завершится. И это совет, который , вероятно, больше не держится на современных JVM: оказывается, что компилятор JIT может решить, в какой момент данная локальная ссылка на объект больше не используется.

Ответ 2

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

См. Эффективное Java 2-е изд., Пункт 6: Устранение устаревших ссылок на объекты.

Ответ 3

Поля экземпляра, элементы массива

Если есть ссылка на объект, сбор мусора невозможен. Особенно, если этот объект (и весь график позади него) большой, есть только одна ссылка, которая останавливает сбор мусора, и эта ссылка больше не нужна, это неудачная ситуация.

Патологические случаи - это объект, который сохраняет unnessary экземпляр для всего дерева XML DOM, который использовался для его настройки, MBean, который не был незарегистрирован, или единственную ссылку на объект из нераспределенного веб-приложения, которое предотвращает весь загрузчик классов от разгрузки.

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

Скопированные переменные:

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

{
  BigObject obj = ...
  doSomethingWith(obj);
  obj = null;          //   <-- explicitly set to null
  doSomethingElse();
}

становится

{
  {  
     BigObject obj = ...
     doSomethingWith(obj);
  }    //         <-- obj goes out of scope
  doSomethingElse();
}

Длинные, плоские области, как правило, плохие для четкости кода. Внедрение частных методов для разрыва только для этой цели тоже не является неслыханным.

Ответ 4

В условиях ограниченной памяти (например, сотовых телефонов) это может быть полезно. Установив нуль, objetc не нужно ждать, пока переменная не выйдет из области действия gc'd.

Однако для повседневного программирования это не должно быть правилом, за исключением особых случаев, подобных цитируемому Крису Джет-Юну.

Ответ 5

Во-первых, это не значит, что вы устанавливаете объект в null. Я объясняю это ниже:

List list1=new ArrayList();
List list2=list1;

В предыдущем сегменте кода, что мы делаем, На самом деле мы создаем список имен ссылочной переменной объекта1 объекта ArrayList, который хранится в памяти. Таким образом, list1 ссылается на этот объект и замечает больше, чем переменную. А во второй строке кода мы копируем ссылку list1 в list2. Итак, вернемся к вашему вопросу, если я это сделаю:

list1=null;

что означает, что list1 больше не ссылается ни на какой объект, который хранится в памяти, поэтому list2 также не будет иметь никакого отношения. Поэтому, если вы проверите размер списка2:

list2.size(); //it gives you 0

Итак, здесь появляется идея сборщика мусора, в которой говорится "вам нечего беспокоиться о освобождении памяти, которая удерживается объектом, я сделаю это, когда найду, что она больше не будет использоваться в программе, а JVM будет управляйте мной".

Я надеюсь, что это ясно.

Ответ 6

Одной из причин этого является устранение устаревших ссылок на объекты. Вы можете прочитать текст здесь.