Прежде всего, вы никогда не должны писать приложения, опираясь на сборщик мусора. Кроме того, даже если вам необходимо взаимодействие с сборщиком мусора, вам следует избегать finalize()
.
. В образовательных целях вы должны знать следующее:
Финализация не мгновенная. System.gc()
не гарантирует, что он идентифицирует конкретный мертвый объект или даже оказывает какое-либо влияние, но когда это происходит, он может ставить в очередь только объект для завершения, поэтому к моменту возврата System.gc()
завершение может еще не завершиться , Возможно, он еще не запустился.
Поскольку финализатор работает в произвольном потоке, он требует обновлений, безопасных для потока.
Сделайте следующее изменения:
Изменение private static int count = 0;
на
private static final AtomicInteger count = new AtomicInteger();
,
далее count += 1;
на count.incrementAndGet();
в каждом конструкторе
и count -= 1;
до count.decrementAndGet();
в методе finalize()
.
и getCount()
до
public static int getCount(){
return count.get();
}
Измените System.gc();
на
System.gc();
Thread.sleep(100);
Вы можете окружить вызов sleep
блоком try...catch
или изменить объявление метода main
, добавив throws InterruptedException
Затем вы можете наблюдать завершение student
экземпляр. Чтобы проиллюстрировать нелогичное поведение программ, полагающихся на сборку мусора, я рекомендую снова запустить программу, теперь с опцией -Xcomp
.
Если у вас JDK 11 или новее, вы можете также выполнить еще один запуск с
-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC
.