Поможет ли GC обнулить локальные переменные в Java? - PullRequest
40 голосов
/ 23 января 2009

Я был вынужден добавить оператор myLocalVar = null; в предложение finally перед выходом из метода. Причина в том, чтобы помочь GC. Мне сказали, что я получу SMS-сообщения ночью, когда сервер в следующий раз выйдет из строя, поэтому я лучше сделал это: -).

Я думаю, что это бессмысленно, так как myLocalVar находится в области действия метода и будет «потерян» при выходе из метода. Дополнительный обнуление просто загрязняет код, но безвреден.

Мой вопрос: откуда взялся этот миф о помощи ГК? (Меня называли «книгами памяти на Java»). Знаете ли вы какую-нибудь статью «авторитетов», которая объясняет это более подробно? Есть ли вероятность, что это не миф, но действительно как-то помогает? Если так, то как? Может ли обнуление локальных переменных причинить какой-либо вред?

Чтобы уточнить, метод выглядит следующим образом:

void method() {
  MyClass myLocalVar = null;
  try {
    myLocalVar = get reference to object;
    ... do more here ...
  } finally {
    if (myLocalVar != null) {
      myLocalVar.close(); // it is resource which we should close
    }

    myLocalVar = null; // THIS IS THE LINE I AM TALKING ABOUT
  }
}

Ответы [ 15 ]

0 голосов
/ 06 апреля 2009

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

0 голосов
/ 04 апреля 2009

Если вам больше не нужны крупные объекты в локальной области видимости, вы можете дать подсказку JVM и установить ссылку NULL.

public void foobar()
{
    List<SomeObject> dataList = new ArrayList<SomeObject>();

    // heavy computation here where objects are added to dataList 
    // and the list grows, maybe you will sort the list and
    // you just need the first element... 

    SomeObject smallest = dataList.get(0);

    // more heavy computation will follow, where dataList is never used again
    // so give the JVM a hint to drop it on its on discretion
    dataList = null;

    // ok, do your stuff other heavy stuff here... maybe you even need the 
    // memory that was occupied by dataList before... 

    // end of game and the JVM will take care of everything, no hints needed
}

Но это не имеет смысла до возврата, потому что это делается JVM автоматически. Так что я согласен со всеми сообщениями до.

0 голосов
/ 23 января 2009

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

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

Когда вы думаете о размещении и освобождении объектов, обратите внимание на вещи, которые обрабатывает «Система»: активные потоки, окна, которые не были утилизированы () d, и еще одну или две вещи, но я могу » не помню прямо сейчас.

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

Большинству классов нужны все переменные-члены для всего их жизненного цикла - и когда их жизнь заканчивается, вся их ветвь обрезается, включая всех их членов; следовательно - нет нуля.

(эти триммеры, кстати, довольно эффективны, даже более бесплатны, чем C ++, поскольку они не требуют прикосновения к каждому объекту при его освобождении)

0 голосов
/ 23 января 2009

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

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

0 голосов
/ 23 января 2009

Я не знаю технических деталей, но, насколько я помню, переменная является не чем иным, как ссылкой из текущего фрейма стека, и до тех пор, пока эта ссылка не будет удалена, объект не может быть собран мусором. Теперь, но явно установив его в null, вы убедились, что ссылка исчезла. Если вы этого не сделаете, вы в основном позволяете ВМ решать, когда очищается эта ссылка, что может или не может происходить при выходе из области (в отличие от C ++, если объект находится в стеке и ДОЛЖЕН быть уничтожен). Это может быть, когда кадр стека перезаписывается следующим. Я не уверен, есть ли виртуальная машина, которая делает это.

Короткий ответ, однако, он не нужен, отметка и развертка получат его в конце концов. Это вопрос времени.

...