Поскольку Java является безопасным языком и платформой, память не освобождается. Также связанные PhantomReference
s не будут ставиться в очередь на их ReferenceQueue
s. Виртуальная машина будет вызывать finalize
только один раз. В спецификации JVM есть хорошая диаграмма состояний.
Обычно, если вы используете финализатор, вы должны оставить объявление как @Override protected void finalize() throws Throwable
, чтобы не нарушать API. Еще лучше использовать защищенный финализатор, как в Effective Java 1st Ed.
Этот конкретный трюк попал в заголовки (во всяком случае, в Сан-Хосе, Меркурий), когда группа в Принстоне использовала его для создания пользовательского ClassLoader
из ненадежного кода. Хотя спецификация была немного ужесточена (конструктор Object
должен нормально завершиться, прежде чем можно будет вызывать финализатор - указанный в J2SE 5.0, реализованном в Java SE 6), это все еще остается проблемной областью. Если вы разрабатываете API, убедитесь, что чувствительные классы не могут быть подклассами, и избавьте себя от горя.