Вы правы в том, что сборщику мусора нужна ссылка на финализуемые объекты.Конечно, эта конкретная ссылка не должна учитываться при принятии решения о том, доступен ли объект до завершения.Это подразумевает специальные знания о природе этой ссылки на сборщик мусора.
Когда сборщик мусора определяет, что объект может быть завершен, запускается финализатор, что подразумевает, что объект снова становится сильно достижимым, впо крайней мере, пока выполняется финализатор.После его завершения объект должен снова стать недоступным, и это необходимо обнаружить, прежде чем память объекта можно будет восстановить.Вот почему требуется как минимум два цикла сборки мусора.
В случае широко используемой среды Hotspot / OpenJDK (и, вероятно, также в JVM IBM) это реализуется путем создания экземпляра специальной, не публичнойподкласс Reference
, a Finalizer
, прямо при создании объекта, класс которого имеет нетривиальный метод finalize()
.Как и в случае со слабыми и мягкими ссылками, эти ссылки ставятся в очередь сборщиком мусора, когда не существует строгой ссылки на референт, но они не очищаются, поэтому поток финализатора может прочитать объект, что снова делает его полностью доступным для финализации.На этом этапе Finalizer
очищается, но также больше не ссылается, поэтому он все равно будет собираться как обычный объект, поэтому к следующему моменту, когда референт станет недоступным, никакой специальной ссылки на него больше не будет.
Для объектов, чей класс имеет «тривиальный финализатор», то есть метод finalize()
, унаследованный java.lang.Object
или пустой метод finalize()
, JVM будет использовать ярлык и не будет создавать экземпляр Finalizer
вВо-первых, можно сказать, что эти объекты, составляющие большинство всех объектов, ведут себя так, как будто их финализатор уже запущен, с самого начала.