2010-09-27 2 views
6

В Java finalize вызывается на объект (который переопределяет его), когда он собирается собирать мусор, поэтому, когда он недоступен. Но что, если финализатор снова сделает объект доступным, что произойдет потом?Что делать, если финализатор делает объект доступным?

ответ

9

Объект не будет собран, пока он не будет снова недоступен.

Согласно JavaDoc, finalize() не будет вызываться снова.

3

Да, именно поэтому вы не используете финализаторы (ну, одна из многих причин).

Существует справочная коллекция, предназначенная для этого. Я посмотрю и отправлю его здесь через секунду, но я думаю, что это PhantomReference.

Да, PhantomReference:

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

+0

Нет, это причина, по которой не писать очень сломанный финализатор (если не было других причин). –

7

Если вы внимательно прочитали описание API, вы увидите, что финализатор может снова сделать объект доступным. Объект не будет отбрасываться, пока он не будет недоступен (снова), но finalize() не будет вызываться более одного раза.

+0

Фактически, финализатор * делает * сделать объект сильно достижимым с помощью корневой ссылки между моментом, когда объект окажется недоступным, и временем запуска его финализатора. Если за это время объект, который был обнаружен недостижимым, становится единственной сохранившейся ссылкой на какой-либо другой объект, этот другой объект не будет собираться до тех пор, пока не будет запущен финализатор или эта ссылка не будет признана недействительной с помощью других средств. – supercat

10

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

3

Это действительно другой проход для проверки и убедитесь, что больше нет ссылок на объект. Так как он не пройдет этот тест на своем втором проходе, вы в конечном итоге не освободите память для объекта.

Поскольку finalize вызывается только один раз для любого заданного объекта, в следующий раз, когда он не имеет ссылок, он просто освободит память, не вызывая завершение. Некоторая хорошая информация here о завершении.

Смежные вопросы