Как для финализируемых объектов требуется не менее 2 циклов сборки мусора, прежде чем его можно будет восстановить? - PullRequest
0 голосов
/ 15 декабря 2018

Я читаю эту статью, и я не могу по-настоящему понять , как для финализируемых объектов (объектов, которые переопределяют метод finalize) требуется как минимум 2 цикла GC, прежде чем его можно будет восстановить.

Требуется, по крайней мере, два цикла сборки мусора (в лучшем случае), прежде чем финализируемый объект может быть возвращен.

Может кто-нибудь также объяснить подробно как возможно, чтобы финализируемый объект взял более одного цикла GC для восстановления?

Мой логический аргумент состоит в том, что когда мы переопределяем метод finalize, среда выполнения должна будет зарегистрировать этот объект с помощьюсборщик мусора (так что GC может вызвать finalize этого объекта, что заставляет меня думать, что GC будет иметь ссылку на все финализируемые объекты).И для этого, GC должен будет строго ссылаться на финализируемый объект.Если это так, то как этот объект стал кандидатом на рекультивацию GC?Я дошел до противоречия с этой теорией.

PS: я понимаю, что переопределение finalize не рекомендуемый подход, и этот метод устарел с Java 9.

1 Ответ

0 голосов
/ 17 декабря 2018

Вы правы в том, что сборщику мусора нужна ссылка на финализуемые объекты.Конечно, эта конкретная ссылка не должна учитываться при принятии решения о том, доступен ли объект до завершения.Это подразумевает специальные знания о природе этой ссылки на сборщик мусора.

Когда сборщик мусора определяет, что объект может быть завершен, запускается финализатор, что подразумевает, что объект снова становится сильно достижимым, впо крайней мере, пока выполняется финализатор.После его завершения объект должен снова стать недоступным, и это необходимо обнаружить, прежде чем память объекта можно будет восстановить.Вот почему требуется как минимум два цикла сборки мусора.

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

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

...