Спецификация Java: пункт 12.7. Выгрузка классов и интерфейсов. 12.8. Выход из программы

12.7. Выгрузка классов и интерфейсов

Реализация языка программирования Java может выгружать классы.

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

Классы и интерфейсы, загруженные загрузчиком начальной загрузки, не могут быть выгружены.

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

Однако, если класс или интерфейс C был выгружен, в то время как его определяющий загрузчик был потенциально доступен, то C может быть перезагружен. Никогда нельзя было гарантировать, что этого не произойдет. Даже если на класс не ссылается какой-либо другой загруженный в данный момент класс, на него может ссылаться какой-либо класс или интерфейс D, который еще не был загружен. Когда D загружается определяющим загрузчиком C, его выполнение может вызвать перезагрузку C.

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

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

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

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

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

12.8. Выход из программы

Программа прекращает всю свою деятельность и завершает работу, когда происходит одно из двух:

  • Все потоки, не являющиеся потоками демона, завершаются.
  • Некоторые потоки вызывают метод exit класса Runtime или класса System, и операция выхода не запрещена диспетчером безопасности.

Читайте также:


Комментарии

Популярные сообщения из этого блога

Методы класса Object в Java

Как получить текущий timestamp в Java

Основные опции JVM для повышения производительности и отладки