2013-04-16 4 views
5

Мне интересно, считаете ли вы хорошей практикой удалять ссылки (устанавливая их на null) на объекты, чтобы помочь сборщику мусора Java.Является ли хорошей практикой удалять ссылки, чтобы помочь GC?

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

Предположим, мне действительно нужны эти два поля, а не только внутренние переменные, поэтому heavyObject1 не может быть недоступен в конце метода.

Вы бы сделали это как обычную практику?

public class TestClass { 

    public static Object heavyObject1; 
    public static Object object2; 

    private static void action() { 
    object2 = doSomething(heavyObject1); 

    heavyObject1 = null; //is this good? 
    } 
} 
+0

Проблема с таким поведением в том, что он несовместим с конечными полями и, таким образом, делает ваш код более надежным для потоковой безопасности. – SpaceTrucker

+0

«Разница» означает выбор того, на что ссылается. Я отредактировал и изменил это. – delnan

ответ

8

Обычно не требуется.

Это хорошая идея в следующих конкретных обстоятельствах:

  • Объект является большим (то есть достаточно большой для вас, чтобы заботиться)
  • Вы уверены, что объект не будет необходимости снова
  • объект не будет выходить за рамки иначе (например, вы знаете, окружающий объект не быть собран мусор)

Однако, если вы оказались в такой ситуации, я подозреваю, что у вас есть запах дизайна: почему внутренний объект имеет такую ​​разную область действия/время жизни от окружающего объекта? Это делает меня подозрительным, потому что обычно, когда вы создаете графический объект с композицией, вы ожидаете, что скомпонованные объекты будут иметь одинаковые сроки жизни.

0

Это, конечно, не плохая практика, чтобы назначить null на ссылки, если вы не хотите больше использовать этот объект. Тем не менее, это Плохая практика, чтобы рассчитывать на GC, чтобы собрать их в любой момент в ближайшее время или вообще во время выполнения вашей программы.

0

Нет, это не нужно. Как только heavyObject1 выходит из области действия, он будет отмечен для GC в любом случае.

+2

Если это поле, оно не выйдет из сферы действия до тех пор, пока объект, в котором он находится, исчез. –

2

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

+0

'heavyObject1' не может выйти из области действия до тех пор, пока' TestClass' не выйдет из области видимости, потому что это поле. – Alphaaa

+1

Правильно ... Но если вам кажется, что нужно сделать это null, это означает, что область тяжелого объекта не определена правильно. Она должна быть либо на уровне экземпляра, либо на уровне метода. – JRR

0

Как общий практика, нет, потому что не нужно.

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

Но в этом и заключается принцип «не нужен».Вы не можете рассчитывать на то, что GC будет работать в течение определенного периода времени, поэтому программа должна поддерживать одновременное использование обоих этих списков в куче, поэтому она не делает вашу программу жизнеспособной, если раньше это было не так.

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

0

Нет. Обычно не рекомендуется делать null поля или местные жители.

В большинстве случаев объект, поле которого вы обнуляете, станет недоступным до запуска GC. Если это произойдет, циклы CPU, которые вы потратили на обнуление поля объекта, будут потрачены впустую.

Единственные ситуации, в которых необходимо/хорошие для null полей/местные жители, где:

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

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

0

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