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


Я только сейчас начинаю изучать внутреннюю архитектуру 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 поддерживает пространства имен загружаемых классов". Под пространствами имен, означает ли это буквальные имена класса? Также может кто-нибудь объяснить значение/преимущество этого?

5 63

5 ответов:

вы будете запускать свой 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 загрузчика классов (или изначальный ). Это необходимое условие для запуска любой программы Java, следовательно, загруженной Bootstrap.

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

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

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

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

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

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

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

Classloader hierarchy

Пространство Имен Загрузчика Классов

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

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

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

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

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

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

// 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<>();

когда класс должен быть добавлен в память следующая функция называется:

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

нашел полезную диаграмму о том, как работают загрузчики классов.

enter image description here

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

читать этой ссылке

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

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

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

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

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

JVM Arch