Java и выполнение финализации вручную

Если я вызову finalize() для объекта из моего программного кода, будет ли JVM снова запускать метод, когда сборщик мусора обрабатывает этот объект?

Это будет приблизительный пример:

MyObject m = new MyObject();

m.finalize();

m = null;

System.gc()

Может ли явный вызов finalize() заставить сборщик мусора JVM не запускать метод finalize() на объекте m?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
17
0
18 944
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Метод finalize никогда не вызывается более одного раза JVM для любого заданного объекта. В любом случае вы не должны полагаться на finalize, потому что нет гарантии, что он будет вызван. Если вы вызываете finalize, потому что вам нужно выполнить код очистки, лучше поместить его в отдельный метод и сделать его явным, например:

public void cleanUp() {
  .
  .
  .
}

myInstance.cleanUp();
Ответ принят как подходящий

Согласно этой простой тестовой программе, JVM по-прежнему будет вызывать finalize (), даже если вы явно вызвали ее:

private static class Blah
{
  public void finalize() { System.out.println("finalizing!"); }
}

private static void f() throws Throwable
{
   Blah blah = new Blah();
   blah.finalize();
}

public static void main(String[] args) throws Throwable
{
    System.out.println("start");
    f();
    System.gc();
    System.out.println("done");
}

Результат:

start
finalizing!
finalizing!
done

Каждый ресурс говорит, что никогда не следует явно вызывать finalize () и почти никогда даже не реализовывать метод, потому что нет никаких гарантий относительно того, будет ли он вызван и когда. Лучше просто закрыть все свои ресурсы вручную.

Чтобы понять функцию финализации, необходимо понимать рабочий процесс сборщика мусора (GC). вызов .finalize () не вызовет ни сборщика мусора, ни system.gc. Фактически, finalize поможет кодеру объявить ссылку на объект как "не имеющую ссылки".

GC принудительно приостанавливает работу JVM, что снижает производительность. Во время работы GC будет проходить по всем ссылочным объектам, начиная с корневого объекта (ваш основной вызов метода). Это время приостановки можно уменьшить, объявив объекты как объекты, на которые нет ссылок вручную, так как это сократит операционные расходы, связанные с объявлением ссылки на объект устаревшей при автоматическом запуске. Объявляя finalize (), кодер устанавливает ссылку на объект как устаревший, таким образом, при следующем запуске операции сборщика мусора выполняется очистка объектов без использования времени операции.

Цитата: «После вызова метода finalize для объекта дальнейшие действия не предпринимаются, пока виртуальная машина Java снова не определит, что больше нет никаких средств, с помощью которых к этому объекту можно получить доступ для любого потока, который еще не умер, включая возможные действия других объектов или классов, которые готовы к завершению, после чего объект может быть отброшен »из Документации по Java API на java.Object.finalize ();

Для подробного объяснения вы также можете проверить: javabook.comкомпьютерное ПО

Другие вопросы по теме