Цитата FinalReference
Этот класс представляет собой тип пакета, указывающий, что он не является публичной частью и наследует от ссылки, что означает, что это также конкретный эталонный тип. Следовательно, до того, как каждый объект, обернутый в него, будет переработан, он будет размещен в указанной Reformebcequeue.
Этот эталонный объект специально используется для класса с помощью методов завершения. Можно понять, что каждый объект с соответствующими методами будет инкапсулировать как объект FinalRefernece.
Поскольку метод завершения определяется объектом, его реализация по умолчанию пуста. Затем, если этот метод переписан, тело метода определенно не будет пустым. Эта разница может быть сделана через это. До тех пор, пока метод завершения реализует класс, который не является пустым, сгенерированные объекты должны быть зарегистрированы в FinalRefernece.
Этот шаг может быть зарегистрирован соответственно, вызывая метод конструктора объекта по умолчанию во время NewInstance.
Finatizer#Метод регистрации
Когда этот метод называется в основном, будет создан соответствующий объект Finalizer, а объект Finalizer унаследован от FinalReference. Этот метод объявлен следующим образом:
/ * Призван VM */Static void Register (Object Finalizee) {New Fintizer (Finalizee);} Как видно из приведенных выше комментариев, этот метод будет вызван JVM в определенный период.
Затем переключитесь на конструктор Finalizer, как показано ниже:
Private Finalizer (Object Finalizee) {Super (Finalizee, Queue); добавлять();} Можно видеть, что соответствующий эталонный объект будет вызван обратно через очередь. Функция ADD - сохранить все объекты, которые еще не завершили метод, и вызовать его в End System.shutdown . Установите его через Runtime#runFinalizersOnExit .
Reference quepueue
Эта справочная очередь будет размещена в этой очереди до того, как внутренние объекты соответствующего эталонного объекта будут переработаны (подробное описание будет объяснено в другой статье о ссылке.), Поскольку только соответствующий объект должен быть получен из этой очереди, тогда этот объект определенно готов к переработке.
Затем вызовите соответствующий метод завершения перед переработкой.
Finalizerthread Thread
Этот поток продолжает получать данные из очереди, а затем вызывает соответствующий метод завершения. Соответствующий код следующим образом:
for (;;) {try {infintizer f = (finalizer) queue.remove (); F.Runfinalizer (JLA); } catch (прерванная экспрессия x) {// игнорировать и продолжить}}Соответствующий runfinalizer заключается в следующем:
синхронизированный (это) {if (hasbeenfinalized ()) return; remove ();} try {object infintize = this.get (); if (finalizee! = null &&! (экземпляр finalizee of java.lang.enum)) {jla.invokefinalize (finalizee); / * Прозрачный слот стека, содержащий эту переменную, чтобы уменьшить шансы на ложное удержание с помощью консервативного GC */ finalizee = null; }} catch (throwable x) {} super.clear ();В вышеупомянутой логике сначала удалите вызов и удалите его из завершения. Этот метод состоит в том, чтобы обеспечить завершение каждого объекта только один раз, то есть текущий вызов завершен. Он будет записан в соответствующем состоянии, то есть HasbeEnfinalized Greats True (на самом деле, это означает, что на него указывают на него следующий указатель. То есть он никогда не был завершен, и нет необходимости вызывать снова завершить).
Далее следует вызвать соответствующий метод завершения. jla.invokeFinalize выше предназначен для того, чтобы вызвать метод завершения соответствующего объекта. В этом процессе исходный объект сначала получен через GET. Во всем процессе JVM эта ссылка не установлена на NULL перед переработкой для Finalizereference. Потому что здесь соответствующий эталонный объект всегда может быть получен.
После обработки соответствующее очищение наконец -то вызвано для очистки соответствующей ссылки. Это достигает эффекта окончательной ссылки, не имеющей другого объекта для ссылки.
В приведенной выше обработке нет ограничений на время, чтобы позвонить в завершение. Следовательно, после того, как завершается завершение объекта медленно, это повлияет на выполнение всей цепочки утилизации, и будет создано соответствующее исключение OOM. Поэтому, если в особых случаях не переписывайте завершайте. Должны быть другие методы для обработки соответствующих сценариев. Например, FinalizableReference в гуаве.
Финализатор запускает нить
В приведенном выше потоке он будет запущен во время соответствующего запуска процесса. Можно понять, что объект запускает инициализацию класса Finalizer, вызывая register(object) . Затем в блоке статической инициализации будет запущена соответствующая потока переработки. Соответствующий код инициализации следующим образом:
static {threadgroup tg = think.currentThread (). getThreadGroup (); for (threadgroup tgn = tg; tgn! = null; tg = tgn, tgn = tg.getParent ()); Thread Finalizer = new Finalizerthread (TG); finalizer.setPriority (thread.max_priority - 2); finalizer.setDaemon (True); finalizer.start ();}Статический выше - это статический блок инициализации, то есть до тех пор, пока используется финализатор класса, будет запускается соответствующий вызов. Группа потоков, используемая здесь, представляет собой группу системных потоков, а приоритет все еще относительно высок, и она настроена как фоновый поток.
При использовании JStack для печати потоков потоки, показанные ниже рисунка, начинаются здесь. Как показано на рисунке ниже
Суммировать
Весь финализатор работает вместе через FinalReference от JVM и соответствующих классов Java. Это не все реализовано JVM, поэтому можно считать, что он не слишком базовый, а для реализации соответствующей семантики. Все сделано нормальной Java и сотрудничает JVM. Понимание всего процесса также является пониманием механизма бега самой Java.