Переменная = ноль установить его для сборки мусора - PullRequest
51 голосов
/ 28 мая 2010

Помогите мне уладить спор с коллегой: Помогает ли установка переменной или коллекции в null в Java для сборки мусора и сокращения использования памяти? Если у меня есть долго работающая программа, и каждая функция может вызываться итеративно (возможно, тысячи раз): помогает ли установка всех переменных в ней на нуль перед возвратом значения родительской функции уменьшить размер кучи / использование памяти?

Ответы [ 8 ]

59 голосов
/ 28 мая 2010

Это старые представления о производительности. Это было верно еще в течение 1,0 дней, но компилятор и JVM были улучшены, чтобы устранить необходимость (если когда-либо была). Эта превосходная статья IBM подробно расскажет, если вам интересно: Теория и практика Java: сборка мусора и производительность

7 голосов
/ 28 мая 2010

Из статьи:

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

Перевод: "явно обнулять" постоянные объекты, которые больше не нужны. (Если хотите. «Фактически требуется» слишком сильное утверждение?)

5 голосов
/ 28 мая 2010

Спецификация Java VM

12.6.1 Реализация финализации Каждый объект может характеризоваться двумя атрибутами: он может быть достижимым, достижимым для финализатора или недоступным, а также может быть незавершенным, финализируемымили завершено.

Достижимым объектом является любой объект, к которому можно получить доступ в любом потенциальном продолжающемся вычислении из любого живого потока .Могут быть разработаны оптимизирующие преобразования программы, которые уменьшают число достижимых объектов до меньшего, чем те, которые наивно считаются достижимыми.Например, компилятор или генератор кода может установить переменную или параметр, которые больше не будут использоваться для обнуления, чтобы в будущем хранилище для такого объекта могло быть потенциально восстановимо.

Обсуждение

Другой пример этого происходит, если значения в полях объекта хранятся в регистрах.Программа может затем получить доступ к регистрам вместо объекта и никогда не получить доступ к объекту снова.Это будет означать, что объект является мусором.

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

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

Другой интересной особенностью Java является то, что область видимости не отображается в файлах классов, поэтому область видимости не имеет отношения к достижимости;эти два метода создают один и тот же байт-код, и, следовательно, виртуальная машина вообще не видит область действия созданного объекта:

static void withBlock () {
    int x = 1;

    {
        Object a = new Object();
    }

    System.out.println(x+1);
}

static void withoutBlock () {
    int x = 1;

    Object a = new Object();

    System.out.println(x+1);
}
3 голосов
/ 28 мая 2010

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

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

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

2 голосов
/ 28 мая 2010

Это бесполезно для локальных переменных, но может быть полезно / необходимо для очистки переменных экземпляра, которые больше не требуются (например, после инициализации).

(Да, да, я знаю, как применить шаблон Builder ...)

1 голос
/ 28 мая 2010

Это может иметь смысл только * в некотором сценарии, подобном этому:

public void myHeavyMethod() {
  List hugeList = loadHugeListOfStuff();  // lots of memory used
  ResultX res = processHugeList(hugeList); // compute some result or summary 
  // hugeList = null;  // we are done with hugeList
    ...
  // do a lot of other things that takes a LOT of time (seconds?)
  // and which do not require hugeList
   ...
}

Вот это может принести некоторую пользу, чтобы раскомментировать строку hugeList = null, наверное.

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

0 голосов
/ 14 июня 2015

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

0 голосов
/ 28 мая 2010

Это хорошо иметь. Когда вы устанавливаете объекты в null, есть вероятность, что объект может быть убран сборщиком мусора быстрее, в непосредственном цикле GC. Но не существует гарантированного механизма для сбора мусора объекта в определенный момент времени.

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