Как JVM начинает искать классы?

  • Мне было интересно, что все места JVM ищут для выполнения программы? Меня больше интересует понимание того, в какой последовательности и где JVM ищет файлы классов, например, он просматривает java-библиотеки, расширения libs, classpath в любой директории, такой как текущий каталог, из которого вызывается Java? Меня больше интересует поведение JVM, а не как класс загрузки загрузчика класса, который, как я знаю, имеет механизм родительского делегирования до root.

  • Если класс выполняется из каталога, в котором скомпилированный класс хранится в файловой системе, а также в файле jar в том же каталоге, будет ли JVM загружаться как один, так и один?

  • Скажите, что у вас есть небезопасный поток Vector, и если мы сравним его производительность с ArrayList, какой из них будет лучше и почему?

Ответ 1

Как классы найдены. Ответ здесь:

http://docs.oracle.com/javase/1.5.0/docs/tooldocs/findingclasses.html

Ответ для пункта 2: Порядок поиска классов выглядит следующим образом:

  • классы или пакеты в текущем каталоге.
  • классы, найденные из переменной среды CLASSPATH. [отменяет 1]
  • классы, найденные в опции командной строки -classpath. [переопределяет 1,2]
  • классы, найденные из архивов jar, заданных с помощью опции командной строки -jar [переопределяет 1,2,3]

Итак, если вы используете параметр -jar во время работы, классы поступают из jarfile.

Загружается только один класс.

Ответ 2

Без использования дополнительного загрузчика классов:

  • Порядок поиска для JVM:
    • Классы выполнения (в основном, rt.jar в $JRE_HOME/lib `)
    • Классы расширения (некоторые JAR в $JRE_HOME/lib/ext `)
    • Путь к классу в порядке. Существует четыре возможности для указания пути к классам:
      • Если указано -jar, то JAR находится в пути к классам. Независимо от того, какой класс path объявлен как classpath в META-INF/MANIFEST.MF, также рассматривается.
      • Если задано -cp, это путь к классам.
      • Else, если установлено $CLASSPATH, то есть путь к классам.
      • Else, текущий каталог, из которого был запущен java, - это путь к классам.
      Итак, если я укажу -cp src/A.jar:src/B.jar, тогда сначала будет поиск A.jar, затем B.jar
  • JVM загружает только класс, который находится первым, в соответствии с порядком, в котором каталоги /JAR объявляются в пути к классам. Это важно, если вы используете -cp или $CLASSPATH.
  • В сценариях с одним потоком и с недавними JVM Vector и ArrayList должны иметь схожую производительность (ArrayList должен работать немного лучше, поскольку это не synchronized, но блокировка выполняется быстро, когда нет конкуренции, поэтому разница должна быть небольшой). Во всяком случае, Vector устарел: не используйте его в новом коде.

Ответ 3

  • Я считаю, что Java просматривается в текущем каталоге, а затем в пути класса к аргументу VM -cp. Вы можете поместить любую комбинацию папок классов (например,/project/bin/com/putable), определенных файлов классов (например,/project/bin/com/putable/MyClass.class) и JAR файлов (например,/project/lib/MyJar.jar) на пути к классу. Местоположения разделяются либо двоеточием (операционные системы на основе Unix), либо точкой с запятой (операционные системы на базе Windows). Итак, что-либо на пути к классам - это справедливая игра для Java, на которую можно смотреть при получении определений классов. Что касается последовательности, классы загружаются лениво. Поэтому они загружаются только тогда, когда ваше приложение сначала требует их. Если ваше приложение не требует определенного класса в течение продолжительности его выполнения, то этот класс НИКОГДА не загружается.

  • Если вы не ставите что-либо на путь класса, я думаю, что Java будет загружаться из файла класса, а не Jar. Если вы укажете один или другой путь в classpath, тогда это место будет искать Java. Если вы поместите оба пути в classpath, поведение загрузки класса Java будет undefined, и оно может выбрать либо в зависимости от реализации JVM.

  • Зависит от того, что вы хотите сделать. Векторы на самом деле всегда потокобезопасны для Java API, поэтому, если вам не нужен одновременный доступ, ArrayList будет быстрее. Векторы и ArrayList поддерживаются массивами, но они увеличивают пропускную способность с разной скоростью (векторная емкость удваивается всякий раз, когда достигается конец, и требуется больше места, но ArrayList увеличивается на 50%). В зависимости от того, как часто вы должны расти или сокращаться, ответ будет отличаться. Посмотрите эту ссылку для получения дополнительной информации:

http://www.javaworld.com/javaworld/javaqa/2001-06/03-qa-0622-vector.html

Ответ 4

Меня больше интересует поведение JVM, а не загрузка загрузчика классов класс

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

Но, возможно, ваш вопрос: как JVM создает загрузчик системного класса?

Ответ 5

Во-первых, по умолчанию система времени выполнения Java использует текущую рабочую в качестве отправной точки. Таким образом, если ваш пакет находится в подкаталоге текущего каталог, он будет найден. Во-вторых, вы можете указать путь к каталогу или пути, установив CLASSPATH. В-третьих, вы можете использовать опцию -classpath с java и javac, чтобы указать путь к вашим классам.
Например, рассмотрим следующую спецификацию пакета:

   пакет MyPack;

Чтобы программа могла найти MyPack, одна из трех вещей должна быть правдой. Либо программа может быть выполнена из каталога, расположенного выше MyPack, или CLASSPATH должен быть чтобы включить путь к MyPack, или параметр -classpath должен указать путь к MyPack когда программа запускается через java. Когда используются два вторых параметра, путь класса не должен включать MyPack. Это должен просто указать путь к MyPack. Например, в среде Windows, если путь для MyPack -

C:\MyPrograms\Java\MyPack

то путь класса к MyPack -

C:\MyPrograms\Java

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