JavaRush /Java блог /Random /Сколько нужно плохих объектов, чтобы заработал finalize()...
Гебби Гудалов
7 уровень

Сколько нужно плохих объектов, чтобы заработал finalize()? Интересные/бесполеные факты

Статья из группы Random
После прочтения лекции 6 level о методе finalize() стало интересно: сколько должно быть мусорных объектов, чтобы рандомный finalize() начал работать? Статья по программированию первая, буду рад вашим пояснениям по нераскрытым топикам в статье. Здесь опишу результат, полученный опытным путём. Придётся убивать котов. Уровень на момет написания статьи - 6. На истину не претендую Обязательно чекните комментарии. После прочтения лекции 6 level о методе finalize() стало интересно: сколько должно быть мусорных объектов, чтобы рандомный finalize() начал работать? Статья по программированию первая, буду рад вашим пояснениям по нераскрытым топикам в статье. Здесь опишу результат, полученный опытным путём. Придётся убивать котов. Сколько нужно плохих объектов, чтобы заработал finalize()? Интересные/бесполеные факты - 1Для эксперимента были использованы два онлайн компилятора. Ресурсы моего компьютера низкие, а на онлайн компиляторе надежда на мощность серверов. Как базовый в работу был взят Online Java Compiler. И такой код:

public class Cat {
   public static int count;
	public static void main(String[] args) {
		for (count = 0; count< 1000000; count++) {
                     Cat cat = new Cat();
                }
	}
	 Cat() { }
	protected void finalize() throws Throwable{
        System.out.println("Я убил кота номер " + count);
    }
}
Далее совершаем первый запуск и... компилятор оказался крайне кровожадным! 16 431 кота зарезал, выбирая рандомно начиная с 622 946 кота. Далее делаем ещё 5 запусков: 708 убитых котов, 25, 1158, 370 и все начинаются примерно с номера 630к +-15к. Также интересно, что концовка ооочень часто выглядит так:

Я убил кота номер 999255
Я убил кота номер 999615
Я убил кота номер 999743
Я убил кота номер 999789
Я убил кота номер 999864
Я убил кота номер 999902
Я убил кота номер 1000000
Я убил кота номер 1000000
Я убил кота номер 1000000
Я убил кота номер 1000000
Я убил кота номер 1000000
Я убил кота номер 1000000
Я убил кота номер 1000000
Откуда повторяющиеся номера, если номер после каждого цикла уникален? Пока ответа не ясен. После закрыл все лишние вкладки в браузере (вдруг на что-то повлияет). Результат следующих 4 тестов примерно такой же. Для чистоты эксперимента применим другой онлайн компилятор с тем же кодом. У него есть ограничение в 183 строки, выводимых на экран, но первые значения всё-такие есть. Тот же около 630 000 номер кота, но уже второго и далее, а вот первый в пяти случаях из пяти оказывался кот около 252 000. А что думаете вы по результатам эксперимента?
Комментарии (4)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Евгений Уровень 15
12 мая 2020
Метод finalize() начиная с java 9 объявлен deprecated. Не используйте метод finalize(). Если необходимо произвести очистку ресурсу после сборки мусора, то необходимо воспользоваться другими средствами: Java 8 и более ранние версии: Использовать PhantomRefrece и RefrenceQueue; Java 9 и более поздние версии: Использовать класс java.lang.ref.Cleaner Больше информации по теме нежелательности использования метода finalize() в этом видео: https://youtu.be/K5IctLPem0c
Justinian Уровень 41 Master
5 мая 2020

public class Solution {
    public static void main(String[] args) {
        for (int i = 0; i < 1_000_000; i++) {
            new Cat();
        }
        System.out.println("End of cycle");
        System.out.println("Finalize count = " + Cat.getFinalizeCount());
    }
}

class Cat {
    private static int count;
    private static int finalizeCount;

    public Cat() {
        count++;
    }

    protected void finalize() throws Throwable {
        finalizeCount++;
        System.out.println("Я убил кота номер " + count);
    }

    public static int getFinalizeCount() {
        return finalizeCount;
    }
}
смотрим вывод:

Я убил кота номер 999968
Я убил кота номер 999986
Я убил кота номер 1000000
End of cycle
Finalize count = 14374
Я убил кота номер 1000000
Я убил кота номер 1000000
Я убил кота номер 1000000
после строки End of cycle было еще 142 штуки строк Я убил кота номер 1000000. Понятно почему. Поскольку переменная статическая, то есть котов мы завершили создавать. Переменная count застыла на значении 1_000_000, а метод finalize продолжает отрабатывать, он берет переменную count, а там застывшее значение 1_000_000. То есть строка "Я убил кота номер " неверна. Она показывает число для совершенно другого кота. Она кота вообще никакого не показыват вернее, она просто берет последнее значение количество созданных котов.