Подтвердить что ты не робот

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

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

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

MyObject m = new MyObject();

m.finalize();

m = null;

System.gc()

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

4b9b3361

Ответ 1

В соответствии с этой простой тестовой программой JVM все равно сделает свой вызов для завершения(), даже если вы явно вызвали его:

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() явно и почти никогда не реализует этот метод, потому что нет никаких гарантий относительно того, когда и когда он будет вызван. Вам лучше просто закрыть все свои ресурсы вручную.

Ответ 2

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

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

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

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

Ответ 3

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

public void cleanUp() {
  .
  .
  .
}

myInstance.cleanUp();