Сведения о вопросе

NOTtoday

08:30, 1st August, 2020

Теги

Java и вручную завершить выполнение

Просмотров: 420   Ответов: 3

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

Это был бы примерный пример:

MyObject m = new MyObject();

m.finalize();

m = null;

System.gc()

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



  Сведения об ответе

fo_I_K

02:21, 18th August, 2020

Согласно этой простой тестовой программе, 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");
}

Выход есть:

начать
заканчиваю!
заканчиваю!
сделано

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


  Сведения об ответе

lool

06:36, 4th August, 2020

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

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

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

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


  Сведения об ответе

LIZA

19:23, 28th August, 2020

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

public void cleanUp() {
  .
  .
  .
}

myInstance.cleanUp();


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться