Поток загрузки классов для простой программы

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

Может кто-то, пожалуйста, ясно объяснить поток загрузки класса, то есть последовательность загрузки загрузочного класса и пользовательскую загрузку классов в примерном Java-коде ниже.

import java.io.File;
public class Sample
{
    public static void main(String[] args)
    {
        String fileName = "sample";
        File file = new File(fileName);
        file.isFile();
    }
} 

Также я узнал из справочного материала, что "classloader поддерживает пространства имен классов, которые он загружает". По пространству имен это означает буквальные имена класса? Также может кто-то объяснить объяснение/преимущество этого?

Ответ 1

Вы выполните свой Sample класс следующим образом

> java Sample

для маленькой магии, проверьте выход опции -verbose:class, и вы увидите тонны следующих строк.

[Opened C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded java.lang.Object from C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded java.io.Serializable from C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded java.lang.Comparable from C:\jdk1.6.0_14\jre\lib\rt.jar]
.
.
.
.
.
.
[Loaded java.security.cert.Certificate from C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded Sample from file:/D:/tmp/]
[Loaded java.lang.Shutdown from C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded java.lang.Shutdown$Lock from C:\jdk1.6.0_14\jre\lib\rt.jar]

Вы видите, что куча классов из \jre\lib\rt.jar загружается, намного раньше, чем ваш класс загружается загрузчиком класса Bootstrap (или Primordial). Это предпосылка для запуска любой программы Java, загруженной Bootstrap.

Другой набор ящиков загружается загрузчиком классов Extension. В этом конкретном примере не было необходимости в каких-либо классах из lib \jre\lib\ext, следовательно, он не был загружен. Но загрузчику класса Extension назначается задача загрузки классов из расширения lib.

EDIT: Помимо стандартных классов Java Java, Sun/Oracle также предоставляют набор баннеров, которые используются для расширения основного API платформы. Банки, помещенные в папку расширения lib, автоматически помещаются в путь к классам и, следовательно, не обязательно должны быть включены в classpath явно. Вот хорошая хорошая официальная статья по той же теме.

Наконец, ваш класс Sample загружается загрузчиком классов Application после того, как Bootstrap и Extension завершили загрузку.

Ответ 2

Иерархия загрузчика классов

Всякий раз, когда запускается новая JVM, загрузчик bootstrap отвечает за загрузку ключевых классов Java (из java.lang package) и других классов времени выполнения в память в первую очередь. Загрузочный загрузчик bootstrap является родителем всех других загрузчиков классов. Следовательно, он является единственным без родителя.

Далее идет расширение classloader. Он имеет загрузчик bootstrap как родительский и отвечает за загрузку классов из всех файлов .jar, хранящихся в пути java.ext.dirs, - они доступны независимо от пути к классам JVMs.

Третий и самый важный класс-загрузчик с точки зрения разработчиков - это системный класс classloader, который является непосредственным дочерним элементом класса loadload. Он загружает классы из каталогов и файлов jar, заданных переменной среды CLASSPATH, системным свойством java.class.path или -classpath параметром командной строки.

Classloader hierarchy

Пространство имен ClassLoader

В Java класс идентифицируется однозначно, используя ClassLoader + Class, поскольку один и тот же класс может быть загружен двумя разными загрузчиками классов.

Class A loaded by ClassLoader A != Class A loaded by ClassLoader B

Как это полезно?

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

Ответ 3

JVM поддерживает пул времени выполнения - это область перменца, где загружаются классы. Всякий раз, когда класс ссылается на defualt class loader, он считает, что класс является классом и загружает его в этот пул. И это не относится к определенным классам или классам, определенным в JDK. Когда упоминается идентификатор класса, он загружается в память.

Классы, загруженные ClassLoader, хранятся внутри экземпляра ClassLoader

// The classes loaded by this class loader. The only purpose of this table
// is to keep the classes from being GC'ed until the loader is GC'ed.
private final Vector<Class<?>> classes = new Vector<>();

Когда класс должен быть добавлен в память, функция follwing называется

// Invoked by the VM to record every loaded class with this loader.
void addClass(Class c) {
    classes.addElement(c);
}

Найдена полезная диаграмма о том, как работают Class Loaders.

enter image description here

Ответ 4

Запустится Java Virtual Machine, создав начальный класс, который указан зависимым от реализации способом, используя загрузчик класса начальной загрузки (§5.3.1). Затем виртуальная машина Java связывает исходный класс, инициализирует его и переменные статического экземпляра, объявленные в нем, и, наконец, вызывает метод public class void main (String []). Вызов этого метода приводит к дальнейшему выполнению. Выполнение инструкций Java Virtual Machine, составляющих основной метод, может привести к связыванию (и, следовательно, созданию) дополнительных классов и интерфейсов, а также вызову дополнительных методов.

прочитайте эту ссылку

Ответ 5

Процесс загрузки можно рассматривать как взаимодействие между Classloader Подсистема и область памяти JVM.

Classloader работает в трех общих шагах 1.) Загрузка 2.) Связывание и 3.) Инициализация.

Самое основное взаимодействие между подсистемой Classloader и Область памяти происходит во время Связывания (кроме других взаимодействий!)

Связывающая деятельность подразделяется на i.) Проверить ii.) Подготовить и iii.) Разрешить. Проверить: больше для обеспечения безопасности, проверена действительная компиляция. На шаге ii.) Подготовка - статическая переменная память распределяется и присваивается значениями по умолчанию. И в

iii.) Решить: Символьные ссылки заменяются оригинальными ссылки из "области метода", которая содержит данные уровня статические переменные.

JVM Arch