Вопрос

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

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

MyObject m = new MyObject();

m.finalize();

m = null;

System.gc()

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

Это было полезно?

Решение

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

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

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

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

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

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

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

public void cleanUp() {
  .
  .
  .
}

myInstance.cleanUp();
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top