Философия Java

Очистка: финализация и сборщик мусора


Программисты знают о важности инициализации, но часто забывают о важности очистки. Помимо всего, кому понадобится очищать значения, типа int? Но с библиотеками, просто “позволить идти своей дорогой” тем объектам, с которыми вы закончили работать не всегда безопасно. Конечно, Java имеет сборщик мусора для освобождения памяти объектов, которые более не используются. Теперь об очень редком случае. Предположим, что ваш объект зарезервировал “специальную” память, не используя new. Сборщик мусора знает только, как освобождать память, выделенную с помощью new, так что он не может освободить “специальную” память объектов. Для обработки этого случая Java обеспечивает метод, называемый finalize( ), который вы можете определить в своем классе. Вот как это должно работать. Когда сборщик мусора готов освободить хранилище, используемое вашим объектом, он сначала вызовет finalize( ), а только на следующем этапе сборки мусора он освободит память объекта. Так что, если вы выбрали использование finalize( ), это даст вам возможность выполнить некоторые важные для очистки операции во время сборки мусора.

Это потенциальная ловушка программистам, так как некоторые из них, особенно программисты на C++, могут ошибочно полагать, что finalize( ) аналогично деструкторам в C++, которые являются функциями, которые всегда вызываются при разрушении объекта. Но в этом заключается важное различие между C++ и Java, потому что в C++ объекты всегда разрушаются (в программах без ошибок), в то время как в Java объекты не всегда попадают под сборку мусора. Или, говоря другими словами:

Сборка мусора - это не разрушение.

Если вы запомните это, вы не встретите трудностей. Это означает, что если есть какие-то действия, которые необходимо выполнить прежде, чем вы закончите работать с объектом, вы должны выполнить эти действия самостоятельно. Java не имеет деструкторов или аналогичной концепции, так что вы должны создать обычный метод для выполнения этой очистки. Например, предположим, что в процессе создания вашего объекта он рисует себя на экране. Если вы явно не вызовите стирание этого изображения с экрана, оно может никогда не очистится. Если вы помещаете некоторое стирание внутри функции finalize( ), то если объект подвергнется сборке мусора, изображение сначала будет стерто с экрана, но если этого не произойдет, то изображение останется. Так что второе, что вы должны запомнить:

Ваши объекты могут не подвергнуться сборке мусора.

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



Содержание раздела