При собеседовании с java-инженерами этот вопрос задают часто, поэтому он требует особого внимания.
Внимательно прочитав эту статью, вы сможете понять, что имеете в виду, и интервью будет полно смеха.
1. Введение в JVM (простое понимание)
Полное имя JVM — виртуальная машина Java, которая предназначена для виртуализации компьютера на компьютере.Это отличается от использования VMWare.Вы можете видеть эту виртуальную вещь, но вы не можете видеть, что эта JVM существует в памяти. Мы знаем, что базовыми компонентами компьютера являются: арифметический блок, контроллер, память, устройства ввода и вывода, затем JVM также имеет этот набор элементов, арифметический блок, конечно же, передается аппаратному центральному процессору и обрабатывается, просто чтобы адаптироваться к «одноразовой компиляции», запускать где угодно», требуется действие перевода, поэтому используется собственный набор команд JVM, который чем-то похож на набор команд сборки. Каждый набор команд сборки нацелен на ряд ЦП , такие как сборка серии 8086. Его можно использовать на 8088, но он не может работать на 8051, и набор команд JVM можно запускать везде, потому что JVM сделала перевод, и переведена на разные машинные языки в соответствии с к разным процессорам.
JVM 中我们最需要深入理解的就是它的存储部分,存储? жесткий диск? NO ,NO , JVM 是一个内存中的虚拟机,那它的存储就是内存了,我们写的所有类、常量、变量、方法都在内存中,这决定着我们程序运行的是否健壮、是否高效,接下来的部分就是重点介绍之。
2. Состав JVM (читайте внимательно)
Эта диаграмма относится к диаграмме состава JVM, широко распространенной в Интернете.Глядя на эту диаграмму, вся JVM разделена на четыре части:
Загрузчик классов Загрузчик классов
Роль загрузчика классов заключается в том, чтобы загрузить файл класса в память.Например, написать программу HelloWord.java, а затем скомпилировать ее в файл класса через javac.Как ее загрузить в память и выполнить? Загрузчик классов берет на себя эту ответственность. Невозможно создать файл .class и загрузить его. Файл класса, загружаемый загрузчиком классов, имеет требования к формату. В «Спецификации JVM» структура файла класса определяется следующим образом:
ClassFile {
u4 magic;
u2 minor_version;
u2 major_version;
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
Если вам нужно разобраться в деталях, вы можете внимательно прочитать главу 4 «Формат файла класса» «Спецификации JVM», которая здесь подробно не объясняется.
Дружеское напоминание: Class Loader загружается только до тех пор, пока он соответствует файловой структуре.Что касается того, может ли он работать или нет, он не отвечает за это, но за это отвечает Execution Engine.
Исполнительный механизм Исполнительный механизм
Механизм выполнения также называют интерпретатором (Interpreter), который отвечает за интерпретацию команд и передачу их операционной системе для выполнения.
Локальный интерфейс Native Interface
Функция локального интерфейса - интегрировать различные языки программирования для Java. Его первоначальное намерение - интегрировать программы C / C ++. Когда Java родилась, когда C / C ++ свирепствовал, чтобы закрепиться, должны быть умный и мудрый вызов программы C/C++, поэтому в памяти специально открывается область для обработки кода, помеченного как нативный.Его особый метод заключается в регистрации нативного метода в стеке нативных методов и загрузке нативных библиотек, когда Execution Engine выполняет. В настоящее время этот метод используется все реже и реже, если только это не приложение, связанное с аппаратным обеспечением, например, управление принтером через программу Java или управление производственным устройством с помощью системы Java.Связь очень развита, например, вы можно использовать связь через сокет, вы также можете использовать веб-службу и т. д., поэтому я не буду подробно рассказывать об этом.
Область рабочих данных Область рабочих данных
Запуск области данных — это центр всей JVM. Все программы, которые мы пишем, загружаются здесь, а затем запускаются, а экосистема Java так процветает из-за хорошей автономии региона.
Весь фреймворк JVM загружается загрузчиком, а затем исполнитель обрабатывает данные в памяти, ему нужно взаимодействовать с гетерогенной системой через локальный интерфейс, и вуаля, рождается полноценная система!
3. Принцип механизма файлов классов загрузки JVM (запомнить хорошо)
Все классы в Java должны быть загружены в JVM загрузчиком классов для запуска. Загрузчик классов сам по себе является классом, и его задача — прочитать файл класса с жесткого диска в память. При написании программ нам вряд ли нужно заботиться о загрузке классов, потому что они загружаются неявно, если у нас нет специального использования, такого как отражение, нам нужно явно загружать требуемые классы.
Существует два типа загрузки классов
1.неявная загрузка, Когда программа встречает объект, сгенерированный новыми и другими методами во время выполнения, она неявно вызывает загрузчик классов для загрузки соответствующего класса в jvm.
2.явная загрузка, явно загружать необходимые классы с помощью таких методов, как class.forname()
Разница между неявной загрузкой и явной загрузкой: одно и то же? Загрузка классов Java является динамической, она не загружает все классы одновременно, а затем запускает их, а гарантирует, что базовые классы (например, базовые классы), на которых работает программа, полностью загружены в jvm. , вам нужно при загрузке. Это, конечно, для экономии памяти.
В Java есть три загрузчика классов.
Три типа, соответствующие Java:
1. Класс системы
2. Класс расширения
3. Классы, настроенные программистами
Bootstrap Loader // 负责加载系统类 (指的是内置类,像是String,对应于C#中的System类和C/C++标准库中的类)
|
- - ExtClassLoader // 负责加载扩展类(就是继承类和实现类)
|
- - AppClassLoader // 负责加载应用类(程序员自定义的类)
Каждый из трех загрузчиков выполняет свою работу, но как они работают вместе? Какой класс должен выполнять какой загрузчик классов? Чтобы решить эту проблему, в Java используется механизм модели делегирования.
Принцип работы механизма модели делегирования очень прост: когда загрузчику класса нужно загрузить класс, он сначала просит своего Родителя (то есть загрузчик верхнего уровня) загрузить его в свой путь поиска, и если он не может его найти , он ищет в своем собственном пути поиска класс. Этот порядок на самом деле представляет собой поиск сверху вниз в иерархии загрузчика, потому что загрузчик должен убедиться, что базовый класс загружен. Причина этого механизма в том, что есть и соображения безопасности: если кто-то загрузит вредоносный базовый класс в JVM, механизм модели делегирования будет искать его загрузчик родительского класса, который, очевидно, невозможно найти, и, естественно, не будет. Загрузите класс.
Мы можем получить загрузчик классов с помощью такого кода:
ClassLoader loader = ClassName.class.getClassLoader();
ClassLoader ParentLoader = loader.getParent();
Обратите внимание на очень важную проблему, то есть в Java логически отсутствует сущность BootstrapKLoader! Поскольку он написан на C++, вывод его содержимого будет нулевым.
Передняя часть представляет собой краткое введение в загрузчик классов.Его принцип и механизм очень просты, которые заключаются в следующих шагах:
1.нагрузка: найти и импортировать файлы классов;
2.соединять:
(1)检查:检查载入的class文件数据的正确性;
(2)准备:为类的静态变量分配存储空间;
(3)解析:将符号引用转换成直接引用(这一步是可选的)
3.инициализация: Инициализировать статические переменные, блоки статического кода.
Этот процесс начинается, когда программа вызывает статические члены класса, поэтому статический метод main() становится методом входа в общую программу. Конструктор класса также вызывает это действие.
Немного подробнее, этапы загрузки
нагрузка
Краткое описание: Перед запуском Java-программы JVM загрузит в память скомпилированный бинарный файл .class, а последующий провайдер будет использовать загрузчик классов ClassLoader. Часть содержимого фазы загрузки и фазы связывания (например, часть действия по проверке формата файла байт-кода) чередуется, и фаза связывания может начаться до завершения фазы загрузки. Однако действия, выполняемые на этапе загрузки, по-прежнему относятся к содержимому этапа подключения.
соединять
-
Подключиться - Аутентифицировать
Проверка — это первый шаг в подключении, цель которого — убедиться, что информация, содержащаяся в потоке байтов файла Class, соответствует требованиям текущей виртуальной машины и не ставит под угрозу безопасность самой виртуальной машины. Этап проверки состоит из четырех этапов: проверка формата файла, проверка метаданных, проверка байт-кода и проверка ссылки на символ.
文件格式检验:检验字节流是否符合Class文件格式的规范,并且能被当前版本的虚拟机处理。
元数据检验:对字节码描述的信息进行语义分析,以保证其描述的内容符合Java语言规范的要求.
字节码检验:通过数据流和控制流分析,确定程序语义是合法、符合逻辑的。
符号引用检验:符号引用检验可以看作是对类自身以外(常量池中的各种符号引用)的信息进行匹配性校验。
-
подключить - подготовить
На этом этапе формально выделяется память для переменных класса и устанавливаются начальные значения переменных класса. Память, используемая этими переменными, будет выделена в области метода. В настоящее время для выделения памяти выделяются только переменные класса, а не переменные экземпляра (переменные экземпляра будут выделены в куче Java вместе с объектом при создании экземпляра объекта). Кроме того, статическая переменная класса, назначенная здесь, должна определить ее значение как значение по умолчанию. Поскольку на этом этапе никакие методы Java не выполняются, правильное назначение будет выполнено на этапе инициализации.
-
подключить - решить
Процесс замены символьных ссылок в пуле констант на прямые ссылки на данном этапе виртуальной машины.
инициализация
Это последний шаг загрузки класса, который фактически выполняет байт-код, определенный в классе, то есть в файле .class. Фаза инициализации — это процесс выполнения методов конструктора класса и фактической инициализации переменных класса и других ресурсов.