Детали сбора мусора: подходит ли этот объект для сбора мусора? - PullRequest
8 голосов
/ 08 мая 2011

Полагаю, что такая программа ...

class Test {
    public static void main(String[] args) {
        new Test();
        System.out.println("done");
    }

    protected void finalize() {
        System.out.println("this object is known to never be referenced.");
    }
}

... может выводить "this object is known to never be referenced." до "done". (Поправь меня, если я здесь не прав!)

Кроме того, компилятору / JVM легко обнаружить «непрочитанные локальные объекты». Например, в приведенной ниже программе Eclipse замечает, что « Локальная переменная t никогда не читается ».

Однако было бы недопустимо, чтобы JVM выдавала "this object is known to never be referenced." до "done" с учетом (версии .class) программы ниже?

class Test {
    public static void main(String[] args) {
        Test t = new Test();
        System.out.println("done");
    }

    protected void finalize() {
        System.out.println("this object is known to never be referenced.");
    }
}

Большая часть документации по сборке мусора говорит о достижимости. Учитывая тот факт, что t никогда не читается, объект явно не «достижим», или?

Ссылки на JLS приветствуются.

Ответы [ 2 ]

5 голосов
/ 08 мая 2011

В 12.6.1 спецификации языка Java говорит:

12.6.1 Реализация финализации

Каждый объект может быть охарактеризован двумя атрибуты: это может быть достижимо, финализатор-достижим или недоступен, и это также может быть незавершенным, Завершается или завершается. Достижимый объект - это любой объект, который может быть доступ к любому потенциальному продолжению вычисления из любого живого потока. Оптимизация преобразований Программа может быть разработана, чтобы уменьшить количество объектов, которые достижимы, чтобы быть меньше тех, которые будет наивно считаться достижимым.

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

Последняя фраза, как мне кажется, охватывает именно тот случай, о котором вы спрашиваете. Переменная t может быть неявно установлена ​​на null до конца области действия, что делает объект недоступным.

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

2 голосов
/ 08 мая 2011

... может выводить «известно, что на этот объект никогда не ссылаются». прежде чем "сделано".

Существует три возможных варианта поведения:

  • сообщение выводится до "готово",

  • сообщение выводится после "done",

  • сообщение «этот объект, как известно, никогда не ссылается» вообще не выводится.

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

Однако для JVM было бы недопустимым выводить «известно, что на этот объект никогда не ссылаются». перед "выполнено", учитывая (.class версию) программы ниже?

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

Однако для появления сообщения должны произойти три события:

  • ГХ должен бежать,
  • ГХ должен обнаружить объект как недостижимый, а
  • ГК должен завершить объект.

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


Суть в том, что вы никогда не должны зависеть от завершения, происходящего в приложении Java.

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