Философия Java


Вы должны выполнять очистку - часть 3


Все это происходит в цикле main( )

while(!Chair.f) { new Chair(); new String("To take up space"); }

Вы можете удивиться, как этот цикл вообще может завершиться, так как внутри нет ничего, что изменяло бы значение Chair.f. Однако finalize( ), в конечном счете, сделает это, когда будет финализован объект номер 47.

Создание объекта String в каждой итерации просто приводит к дополнительному выделению места для ускорения запуска сборщика мусора, который начнет действовать, когда будет озабочен количеством доступной памяти.

Когда вы запускаете программу, вы передаете аргумент командной строки “gc,” “finalize,” или “all”. Аргумент “gc” приведет к вызову метода System.gc( ) (для форсирования работы сборщика мусора). Использование “finalize” приведет к вызову System.runFinalization( ), который, теоретически, является причиной того, что не финализированные объекты будут финализированы. А “all” станет причиной вызова обоих методов.

Поведение этой программы в версии первой редакции этой книги показывает, что все проблемы сборки мусора и финализации эволюционировали, и большинство эволюции произошло за закрытыми дверями. Фактически, в то время, когда вы читаете это, поведение программы может снова изменится.

Если вызван System.gc( ), то финализация происходит для всех объектов. Это не было необходимо с предыдущей реализацией JDK, хотя документация заявляла обратное. Кроме того, вы увидите, что кажется, что нет каких-то различий, произошел ли вызов System.runFinalization( ).

Однако вы увидите, что если System.gc( ) вызывается после того, как все объекты будут созданы и работа с ними будет завершена, то будут вызваны все методы финализации. Если вы не вызываете System.gc( ), то только некоторые из объектов будут финализированы. В Java 1.1 метод System.runFinalizersOnExit( ) был введен, чтобы являться причиной, заставляющей запускать всех методов финализации при выходе из программы, но при этом в дизайне появлялось много ошибок, поэтому метод устарел и был заменен. Это дает представление о том, какие искания предпринимали разработчики Java в попытках решить проблемы сбора мусора и финализации. Мы можем только надеяться, что эти вещи достаточно хорошо разработаны в Java 2.

Предыдущая программа показывает, что обещание, что все финализации всегда выполняются, справедлива только, если вы явно навязываете, чтобы это происходило. Если вы не вызываете System.gc( ), на выходе вы получите примерно следующее:

Created 47 Beginning to finalize after 3486 Chairs have been created Finalizing Chair #47, Setting flag to stop Chair creation After all Chairs have been created: total created = 3881, total finalized = 2684 bye!

Таким образом, не все финализации вызываются до того, как программа завершится. Если вызван System.gc( ), это приведет к финализации и разрушению всех объектов, которые более не используются в этот момент.

Помните, что ни сборка мусора, ни финализация не гарантирована. Если Виртуальная Java Машина (JVM) не приближается к переполнению памяти, то она (что очень мудро) не тратит время на освобождение памяти с помощью сборки мусора.




Начало  Назад  Вперед