Объекты присвоения аннулировать в Java влияют на сборку "мусора"?

82
задан Raedwald 9 November 2017 в 07:33
поделиться

11 ответов

Как правило, нет.

, Но как все вещи: это зависит. GC в Java в эти дни ОЧЕНЬ хорош, и все должно быть очищено очень вскоре после того, как это больше не достижимо. Это сразу после оставляет метод для локальных переменных, и когда на экземпляр класса больше не ссылаются для полей.

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

, Например, этот код от ArrayList:

public E remove(int index) {
    RangeCheck(index);

    modCount++;
    E oldValue = (E) elementData[index];

    int numMoved = size - index - 1;
    if (numMoved > 0)
         System.arraycopy(elementData, index+1, elementData, index,
             numMoved);
    elementData[--size] = null; // Let gc do its work

    return oldValue;
}

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

Оба:

void foo() {
   Object o = new Object();
   /// do stuff with o
}

и:

void foo() {
   Object o = new Object();
   /// do stuff with o
   o = null;
}

функционально эквивалентны.

63
ответ дан Mark Renouf 24 November 2019 в 09:18
поделиться

По моему опыту, как правило, люди пустой указатель ссылки из паранойи не из необходимости. Вот быстрая инструкция:

  1. , Если объект ссылки возражают B и , Вам больше не нужна эта ссылка и , объект A не имеет право на сборку "мусора" тогда, необходимо явно аннулировать поле. Нет никакой потребности аннулировать поле, если вложенный объект добирается, собрал "мусор" так или иначе. При обнулении полей в расположении () метод почти всегда бесполезен.

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

я сказал бы, что подавляющее большинство времени Вы не должны будете аннулировать ссылки. Попытка перехитрить сборщик "мусора" бесполезна. Вы только закончите с неэффективным, нечитабельным кодом.

11
ответ дан 2 revs, 2 users 92% 24 November 2019 в 09:18
поделиться

Хорошая статья сегодняшняя ужас кодирования .

способ, которым работа GC путем поиска объектов, которые не имеют никаких указателей на них, областью их поиска является "куча"/стек и любые другие пробелы, которые они имеют. Таким образом, при установке переменной в NULL на фактический объект теперь не указывает никто, и следовательно мог быть GC'd.

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

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

Так, таким образом, да это может помочь, но это не будет детерминировано .

11
ответ дан earlNameless 24 November 2019 в 09:18
поделиться

По крайней мере, в Java, это не шаманское программирование вообще. При создании объекта в Java с помощью чего-то как

Foo bar = new Foo();

, Вы делаете две вещи: во-первых, Вы создаете ссылку на объект, и во-вторых, Вы создаете сам объект Foo. Пока та ссылка или другой существуют, конкретный объект не может быть gc'd. однако при присвоении пустого указателя той ссылке...

bar = null ;

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

8
ответ дан Charlie Martin 24 November 2019 в 09:18
поделиться

Это зависит.

Вообще говоря, короче Вы сохраняете ссылки на свои объекты, быстрее они будут собраны.

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

Так или иначе, установка в NULL всех ссылок по умолчанию является мне преждевременной оптимизацией, и никто не должен делать это, если в определенных редких случаях, где это в известной мере уменьшает память consuption.

7
ответ дан lubos hasko 24 November 2019 в 09:18
поделиться

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

ссылки установки в NULL Generally, подразумевайте для ЧИТАТЕЛЯ кода, что этот объект полностью сделан с и не должен касаться больше.

А подобный эффект может быть достигнут путем представления более узкого объема путем включения дополнительного набора фигурных скобок

{
  int l;
  {  // <- here
    String bigThing = ....;
    l = bigThing.length();
  }  // <- and here
}

, это позволяет bigThing быть собранным "мусор" прямо после отъезда вложенных фигурных скобок.

6
ответ дан Thorbjørn Ravn Andersen 24 November 2019 в 09:18
поделиться

Да.

От "Прагматически настроенного Программиста" p.292:

установка By ссылка для ОБНУЛЕНИЯ Вас сокращает количество указателей на объект одним... (который позволит сборщику "мусора" удалять его)

2
ответ дан 24 November 2019 в 09:18
поделиться

Я предполагаю, что OP относится к вещам как это:

private void Blah()
{
    MyObj a;
    MyObj b;

    try {
        a = new MyObj();
        b = new MyObj;

        // do real work
    } finally {
        a = null;
        b = null;
    }
}

В этом случае, разве VM не отметил бы их для GC, как только они оставляют объем так или иначе?

Или, с другой точки зрения, был бы, явно устанавливая объекты на пустой указатель, заставляют их получать GC'd, прежде чем они были бы, если они просто вышли из объема? Если так, VM может провести время GC'ing объект, когда память не необходима так или иначе, который на самом деле вызвал бы худшее использование ЦП производительности, мудрое, потому что это будет GC'ing, больше ранее.

1
ответ дан CodingWithSpike 24 November 2019 в 09:18
поделиться

" Это зависит ",

я не знаю о Java, но в .net (C#, VB.net...), это обычно не требуется присвоить пустой указатель, когда Вы больше не требуете объекта.

Однако примечание, что это "обычно не требуется".

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

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

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

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

Некоторые ссылки по теме:

http://blogs.msdn.com/csharpfaq/archive/2004/03/26/97229.aspx

http://weblogs.asp.net/pwilson/archive/2004/02/20/77422.aspx

0
ответ дан Sesh 24 November 2019 в 09:18
поделиться
public class JavaMemory {
    private final int dataSize = (int) (Runtime.getRuntime().maxMemory() * 0.6);

    public void f() {
        {
            byte[] data = new byte[dataSize];
            //data = null;
        }

        byte[] data2 = new byte[dataSize];
    }

    public static void main(String[] args) {

        JavaMemory jmp = new JavaMemory();
        jmp.f();

    }

}

Вышеупомянутая программа выдает OutOfMemoryError . Если раскомментировать data = null; , ошибка OutOfMemoryError будет устранена. Всегда рекомендуется устанавливать для неиспользуемой переменной значение null

5
ответ дан 24 November 2019 в 09:18
поделиться

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

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

0
ответ дан 24 November 2019 в 09:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: