Ответ 1
Но как может только один пустой финализированный вызов прерывать GC/JVM?
Когда есть финализатор, объекты переживают еще один раунд сбора мусора, чем в противном случае (поскольку сам объект должен быть сохранен до его завершения). Поэтому, если у вас есть большой объект с финализатором, это естественно приведет к OutOfMemoryError
, возникающему в ситуациях, когда он не будет без финализатора.
В этом коде:
A a1 = new A();
a1 = null;
A a2 = new A();
... GC будет вызываться на последней строке, чтобы попытаться найти достаточно памяти для выделения второго A
. К сожалению, он не может мусор собирать первый A
(и массив, на который он ссылается), потому что финализатор еще не запущен. Он не дожидается завершения финализатора, а затем попытается снова собрать мусор - он просто бросает OutOfMemoryError
.