Как войти, когда метод finalize не был вызван? - PullRequest
0 голосов
/ 08 ноября 2019

Я не использую метод finalize в своем приложении, но этот вопрос из любопытства.

Предположим, что в классе есть метод finalize, и я хотел бы записать предупреждение о том, что finalize не был вызван.

Как это сделать?

Есть советы?

Ответы [ 2 ]

1 голос
/ 08 ноября 2019

Две возможности - в любом случае вам понадобится одноэлементная коллекция.

1) Когда каждый объект создается, добавьте уникальный ключ (String), который идентифицирует объект - (но не сам объект!) В коллекцию. Когда вызывается финализатор, удалите его ключ из коллекции.

В любой момент времени в коллекции доступны выдающиеся экземпляры.

2) Хорошо, вы МОЖЕТЕ добавить сам объект вколлекция, если вы действительно хотите, но коллекция должна быть коллекцией соответствующего ссылочного класса. Это сложнее и требует небольшого исследования - посмотрите на справочные классы (WeakReference / PhantomReference / ??). Я не смотрел на них в течение нескольких лет и точно забыл, кто что делает, но это именно та работа, для которой были созданы Справочные классы.

Будьте осторожны с 2, я думаю, что естьвероятность того, что итерация по коллекции ссылок может воскресить мертвый класс или остановить его сбор.

Причина обоих предостережений заключается в том, что если вы сохраните ссылку в обычной коллекции, она никогда не будет иметь право на коллекцию, поэтому нетФинализатор когда-нибудь будет вызван.

0 голосов
/ 08 ноября 2019

JVM гарантирует, что метод будет вызван до удаления объекта, согласно JLS 12.6. Завершение экземпляров класса :

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

Вы пытаетесь доказать, что JVM не следует JLS, что было бы ошибкой.

Глядя на исходный код Azul Zulu OpenJDK 11, мы видим, что финализации выполняются с java.lang.ref.Finalizer объект, который в свою очередь использует метод jdk.internal.misc.JavaLangAccess.invokeFinalize(Object) для вызова Object.finalize().

JavaLangAccess экземпляр получен из jdk.internal.misc.SharedSecrets, что позволяет настроить пользовательский экземпляр JavaLangAccess. Возможно, вы могли бы создать свой собственный экземпляр JavaLangAccess с дополнительной регистрацией в методе invokeFinalize()?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...