Это помогает GC аннулировать локальные переменные в Java

Этот подход был одобрен @James_D в комментарии.

Просто добавьте промежуток H и V ширины одного пикселя и позвольте фоновому цвету панели сетки «сиять» через:

.my-grid-pane {
    -fx-background-color: lightgray;
    -fx-vgap: 1;
    -fx-hgap: 1;
    -fx-padding: 1;
}

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

40
задан Scott Dorman 12 February 2009 в 06:53
поделиться

15 ответов

Была старая часть документации Sun, Функционирование Платформы Java (связь, печально теперь разорванная, и я не смог найти новый), который описал ситуацию, где обнуление локальной переменной, которая выпала из объема на самом деле, имело эффект на GC.

Однако бумага упомянула очень старую версию Java. Как упомянуто в этот вопрос (который также содержит prГ©cis проблемы, описанной в газете), это больше не влияет на текущие реализации JVM.

29
ответ дан biziclop 23 September 2019 в 16:28
поделиться

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

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

0
ответ дан Michael Myers 23 September 2019 в 16:28
поделиться

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

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

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

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

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

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

0
ответ дан Bill K 23 September 2019 в 16:28
поделиться

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

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

1
ответ дан Dave Costa 23 September 2019 в 16:28
поделиться

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

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

0
ответ дан falstro 23 September 2019 в 16:28
поделиться

Существует только два случая, где я нашел, что установка в NULL переменной была полезна:

  • В модульных тестах, которые создают большой объект в поле. Тестер единицы может сохранить тестовый объект и объекты, которые Вы создали для жизни всех тестов. Это может заставить у тестера заканчиваться память. В этом случае часто лучше использовать локальные переменные вместо полей, но если поле потребовало, чтобы это могло быть очищено в разрушении.
  • Циклические ссылки могут быть очищены GC, но не с простым возрастающим набором. Это может означать, что объекты с циклическими ссылками берут больше работы для очистки и могут жить очень долго, чем они были бы иначе. Обычно это не имеет значения, но при попытке уменьшить свое целое время GC, оно может помочь повредить циклические ссылки.
1
ответ дан Michael Myers 23 September 2019 в 16:28
поделиться

Вы корректны. Обнуление переменной, которая сразу упадет из объема так или иначе, является ненужным и не имеет никакого значения вообще к GC. Все, что это делает, создать помехи коду. В Эффективный Java 2-й Выпуск , автор рекомендует против ненужного обнуления из локальных переменных. Посмотрите Эффективный Java, 2-й Выпуск, Объект 6: Устраните устаревшие ссылки на объект для полной рецензии.

можно также видеть это в статье Создающие и Уничтожающие Объекты Java в InformIT. Читайте вся статья для нахождения места, где Joshua Bloch соглашается с Вами.

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

РЕДАКТИРОВАНИЕ: Добавьте ссылку к Эффективному Java 2-й Выпуск в веб-сайте Sun

3
ответ дан Eddie 23 September 2019 в 16:28
поделиться

Не в этом случае. myLocalVar падает из объема, как только функция возвращается, так установка в NULL ссылки абсолютно ничего не делает.

9
ответ дан Outlaw Programmer 23 September 2019 в 16:28
поделиться

Это - миф, который идет путем назад к тому, когда Java сначала вышел, и парни C++ не доверяли gc

, gc знает то, что это делает. обнуление привычки var повредило что-либо, но это привычка действительно помогает чему-либо также. Jeff имел довольно забавное сообщение на этом просто на днях.

8
ответ дан Matt Briggs 23 September 2019 в 16:28
поделиться

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

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

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

SomeResult SomeFunction(SomeClass param) {
    TempData big = new TempData(param);
    IntermediateResult intermediate = big.GetIntermediateResult();
    big = null; // allow GC to reclaim the memory before returning from the function
    intermediate.FurtherProcessing();
    return intermediate.EvenMoreProcessing();
}
5
ответ дан David Schmitt 23 September 2019 в 16:28
поделиться

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

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

я не уверен, применялось ли это с современным VM. Сборщики "мусора" стали все больше более умными.

2
ответ дан krosenvold 23 September 2019 в 16:28
поделиться

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

public class Main {
    public static void main(String[] args) {
       {
           Main local = new Main();

           // inner = null;
       }

       while (true) {
           // long running method
       }
    }
}

, Если inner = null; комментируется, объект в local, переменная не может быть собрана "мусор" во время цикла с условием продолжения. Причина состоит в том, что виртуальная машина Java не знает об объемах как это. Все, что это имеет:

D:\workspaces\workspace-3.4\test\src>javap -verbose -c Main
public class Main extends java.lang.Object
  minor version: 0
  major version: 50
  Constant pool:
const #1 = Method       #4.#11; //  java/lang/Object."<init>":()V
const #2 = class        #12;    //  Main
const #3 = Method       #2.#11; //  Main."<init>":()V
const #4 = class        #13;    //  java/lang/Object
const #5 = Asciz        <init>;
const #6 = Asciz        ()V;
const #7 = Asciz        Code;
const #8 = Asciz        main;
const #9 = Asciz        ([Ljava/lang/String;)V;
const #10 = Asciz       StackMapTable;
const #11 = NameAndType #5:#6;//  "<init>":()V
const #12 = Asciz       Main;
const #13 = Asciz       java/lang/Object;

{
public Main();
  Code:
   Stack=1, Locals=1, Args_size=1
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   Stack=2, Locals=2, Args_size=1
   0:   new     #2; //class Main
   3:   dup
   4:   invokespecial   #3; //Method "<init>":()V
   7:   astore_1
   8:   goto    8
  StackMapTable: number_of_entries = 1
   frame_type = 8 /* same */

}

нет никакой информации об объеме локальной переменной. Таким образом с точки зрения JVM, выше программы эквивалентно:

public class Main
{

    public Main() { }

    public static void main(String args[])
    {
        Main main1 = new Main();
        do
            ;
        while(true);
    }
}

(Сгенерированный декомпилятором JAD)

Заключение: СУЩЕСТВУЕТ некоторое объяснение в обнулении локальных переменных в совершенно особых случаях как это. Но если метод собирается закончиться скоро (как в моем исходном вопросе), он не помогает.

Это было вдохновлено комментарием от Zdenek Tronicek в списке рассылки java-cz (на чешском языке, извините)

3
ответ дан Peter Štibraný 23 September 2019 в 16:28
поделиться

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

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

Другие люди помещают локальные переменные в переменную экземпляра (например, путем передачи его для функционирования), и затем думают, что аннулирование локальной переменной так или иначе устраняет переменную, которая, конечно, неверна.

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

Так да, Вы корректны, что это является ненужным.

19
ответ дан SCdF 23 September 2019 в 16:28
поделиться

Мало того, что обнуление является локальной переменной как этот бессмысленный с точки зрения GC, оно может вызвать ненужную загрузку переменной в регистр для обнуления его, который делает ситуацию хуже. Вообразите, существует ли 1 000 строк кода между последним чтением, или запишите в myLocalVar, и затем Вы ссылаетесь на него только к пустому указателю ссылка. Значение давно в прошлом от регистра, но необходимо загрузиться, это въезжает задним ходом к памяти для работы с ним.

0
ответ дан Kai 27 November 2019 в 01:28
поделиться

Если Вам не нужны большие объекты в Вашем локальном объеме еще, можно дать JVM подсказку и установить ссылочный ПУСТОЙ УКАЗАТЕЛЬ.

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
ответ дан ReneS 27 November 2019 в 01:28
поделиться
Другие вопросы по тегам:

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