Загрузка классов Java, которые не нужны - PullRequest
4 голосов
/ 10 июня 2009

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

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

Это позволяет просто удалять пользовательские классы в каталоге и загружать их и регистрировать.

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

Влияет ли просто загрузка классов на память?

Ответы [ 5 ]

4 голосов
/ 10 июня 2009

Как обычно, я бы посоветовал измерить это для вашего конкретного сценария.

Сказав это, я не уверен, что посоветовал бы сканировать целом classpath. Если вы не контролируете classpath (это ваш клиент или аналогичный), потенциально они могут добавить к нему что угодно, и ваш процесс будет сканировать все, что попадет в их classpath (возможно, не связанный с вашим приложением).

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

2 голосов
/ 10 июня 2009

Если вы используете отдельный ClassLoader для загрузки этих классов и очень осторожны , чтобы не создавать никаких ссылок на эти классы или их экземпляры, то когда ClassLoader становится пригодным для сборки мусора, то и классы .

Таким образом, вы можете избежать ненужного засорения пространства PermGen, выполнив 2 прохода с отдельными загрузчиками классов: один для загрузки всех классов и определения тех, которые вы хотите сохранить, а другой для их фактического использования.

1 голос
/ 10 июня 2009

Не будет ли использование ClassLoaders таким образом иметь непредвиденные побочные эффекты? Например, запуск статических инициализаторов и т. Д.

Вы можете использовать механизм ServiceLoader , но если это не подходит, вы можете проверять классы без использования ClassLoaders - библиотеки манипулирования байтами, такие как BCEL и ASM Может использоваться только для проверки классов.

0 голосов
/ 10 июня 2009

Предложение "далеко там":

не могли бы вы сделать то же самое, но без использования виртуальной машины? спецификация файла класса задокументирована, не могли бы вы написать свое собственное приложение, чтобы просто прочитать файлы класса и выяснить, реализуют ли они ваш интерфейс / что-то еще, фактически не загружая их?

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

0 голосов
/ 10 июня 2009

Да, это заставляет виртуальную машину загружать файл класса и проверять его (что может быть проблемой производительности). Более того, если вы используете виртуальную машину Sun, эти классы останутся в памяти навсегда. виртуальная машина Sun помещает классы в так называемое пространство «PermGen», которое никогда не собирается сборщиком мусора, если вы не укажете специальный параметр.

Так что, как правило, это плохая идея, но есть два простых обходных пути:

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

  2. Используйте две директории. Один содержит нормальные классы, другой - все те, которые вы хотите всегда загружать.

...