Неэффективен ли большой путь к классу из нескольких (возможно, даже неиспользуемых) файлов JAR - PullRequest
17 голосов
/ 21 декабря 2011

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

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

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

Является ли ссылка на каталог лучшим вариантом?Или файл Jar уже разархивирован во временную папку для начала?

Быстрее ли использовать метод каталога, чем метод файла Jar?

Разумно ли извлечь все файлы Jar водин каталог, чтобы уменьшить количество мест в пути к классам?Когда это хорошая идея?

Ответы [ 3 ]

11 голосов
/ 21 декабря 2011

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

В случае большого количества JAR я бы больше беспокоился о JAR Hell .

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

Я думаю, гладкий ответ регги хорош для некоторых дополнительных деталей по теме загрузки класса.

7 голосов
/ 21 декабря 2011

Центральные каталоги jar-файлов (помещенные в конце почтовых индексов) будут проанализированы и загружены в память. Каталог плоский, поэтому все это нужно загрузить. Значительная часть задержки при запуске простого Java-процесса - открытие огромного файла rt.jar. Так что да, это время запуска и нехватка памяти прямо здесь.

Посмотрите, для каждого класса должно быть постоянное время. Однако там есть несколько O (n) алгоритмов. Таким образом, для приложения в целом, что O (n ^ 2) для загрузки класса (хотя константа довольно мала и вполне может доминировать линейные операции времени).

Доступ к файлам при загрузке файлов будет неэффективным. JDK использовал zip для системных классов перед jars.

(Загрузка класса может произойти за некоторое время до статической инициализации, когда статический инициализатор будет запущен, если имеется - см. Три аргумента Class.forName.)

3 голосов
/ 21 декабря 2011

Как найти классы и Глава о загрузке, связывании и инициализации в спецификации JVM - это полезные ссылки.

Исходя из личного опыта, я могу засвидетельствовать, что чем дольше ваш classpath для javac, тем больше времени займет ваша компиляция; это особенно проблема, когда ваш путь к классам содержит JAR-файлы, которые не требуются для компиляции. Для простого теста попробуйте скомпилировать канонический HelloWorld.java без -cp, с парой файлов JAR, добавленных к -cp, а затем с несколькими файлами JAR, добавленными к -cp; время, необходимое для компиляции, увеличивается с увеличением числа JAR-файлов в списке -cp.

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