Страницы

Поиск по вопросам

пятница, 13 декабря 2019 г.

Сколько объектов будут недоступны, и поэтому могут быть удалены, если сборщик мусора запустится сразу после выполнения следующего кода:

#java #сборщик_мусора


Ситуацию МОЖНО воспроизвести: достаточно просто воспроизвести следующий код. И вопрос
задан по существу и касается механизма работы сборщика мусора.

Если сборщик мусора запустится сразу после выполнения m1 = null; m2 = null;, то сколько
объектов будет недоступны, и поэтому могут быть удалены сборщиком мусора?

public class MyTest {
    MyTest m;

    void show() {
        System.out.println("Привет, Мир.");
    }

    public static void main(String args[]) {
        MyTest m1 = new MyTest();
        MyTest m2 = new MyTest();
        MyTest m3 = new MyTest();
        m1.m = m2;
        m2.m = m3;
        m3.m = m1;
        m1 = null;
        m2 = null;
        // Вопрос: если сборщик мусора запустится здесь, то сколько объектов будет
недоступны, и поэтому могут быть удалены сборщиком мусора?
    }
}

    


Ответы

Ответ 1



Вы удивитесь, но правильный ответ - Implementation defined. В том смысле, что в зависимости от реализации JVM могут быть освобождены хоть все объекты MyTest, хоть ни одного. И в обоих случаях поведение будет абсолютно корректным по отношению к Java Language Specification и Java Memory Model. Докажу на примере: public static void main(String args[]) { MyTest m1 = new MyTest(); MyTest m2 = new MyTest(); MyTest m3 = new MyTest(); m1.m = m2; m2.m = m3; m3.m = m1; m1 = null; m2 = null; // Слабая ссылка обнулится, как только объект m3 будет собран WeakReference ref = new WeakReference<>(m3); for (int i = 0; ref.get() != null; i++) { if ((i % 1000) == 0) System.gc(); } System.out.println("m3 is garbage-collected"); } После нескольких тысяч итераций цикла метод скомпилируется JITом, ссылок на объект m3 больше не будет, и он удалится после очередной сборки мусора. Однако если запустить Java с флагом -Xint, то ссылка на m3 всегда будет лежать доступной на стеке, и программа зациклится. Забавно, но факт: даже объект this может быть освобождён сборщиком мусора прямо во время выполнения метода на этом объекте. Подробности в JDK-8055183. В Java 9 даже будут дополнения к Java Memory Model и специальный метод Reference.reachabilityFence, чтобы избежать подобных курьёзов.

Комментариев нет:

Отправить комментарий