Як працює JVM - Архітектура JVM
Віртуальна машина Java (JVM) є основним компонентом Java Runtime Environment (JRE), який дозволяє програмам Java працювати на будь-якій платформі без змін. JVM діє як інтерпретатор між байт-кодом Java і основним апаратним забезпеченням, надаючи відому можливість Java Write Once Run Anywhere (WORA).
- Джерело Java (.java) -> скомпільовано javac -> байт-код (.class)
- JVM завантажує байт-код, перевіряє його зв’язок, а потім виконує
- Виконання може передбачати інтерпретацію байт-коду або використання Just-In-Time (JIT) компіляції для перетворення гарячого коду у рідний машинний код для підвищення продуктивності
- Збирання сміття виконується у фоновому режимі, щоб звільнити пам’ять від невикористаних об’єктів
Архітектура JVM
На зображенні нижче показано архітектуру та ключові компоненти JVM.
Компоненти архітектури JVM
Тепер ми детально обговоримо кожен компонент JVM.
1. Підсистема завантажувача класів
Він в основному відповідає за три види діяльності.
1. Завантаження
- Читає файли .class і зберігає метадані класу в області методів.
- Створює об’єкт Class у купі, що представляє завантажений клас.
class GFG { static { System . out . println ( 'GFG class is loaded by the JVM!' ); } public void display (){ System . out . println ( 'Method of GFG class is executed.' ); } } public class Test { public static void main ( String [] args ) throws Exception { System . out . println ( 'Main method started.' ); // Loading the class explicitly using Class.forName() Class . forName ( 'GFG' ); System . out . println ( 'Class loaded successfully.' ); // Creating object to execute method GFG obj = new GFG (); obj . display (); } }
Вихід
Main method started. GFG class is loaded by the JVM! Class loaded successfully. Method of GFG class is executed.
Примітка: За кожен завантажений .клас лише файл один створено об'єкт класу.
2. Посилання: Відповідає за підготовку завантаженого класу до виконання. Він включає три кроки:
- Перевірка: Гарантує, що байт-код відповідає правилам JVM і безпечний для виконання.
- Приготування: Виділяє пам'ять для статичних змінних і призначає значення за замовчуванням.
- роздільна здатність: Перетворює символічні посилання на прямі посилання в пам’яті.
3. Ініціалізація
- Призначає фактичні значення статичним змінним.
- Виконує статичні блоки, визначені в класі.
Типи завантажувача класів
- Завантажувач класів Bootstrap: Завантажує основні класи Java (JAVA_HOME/lib).
- Завантажувач класів розширення: Завантажує класи з каталогу розширень (JAVA_HOME/jre/lib/ext).
- Завантажувач класу системи/програми: Завантажує класи з шляху до класів програми.
// Java code to demonstrate Class Loader subsystem public class Geeks { public static void main ( String [] args ) { // String class is loaded by bootstrap loader and // bootstrap loader is not Java object hence null System . out . println ( String . class . getClassLoader ()); // Test class is loaded by Application loader System . out . println ( Geeks . class . getClassLoader ()); } }
Вихід
null jdk.internal.loader.ClassLoaders$AppClassLoader@8bcc55f
2. Області пам’яті JVM
- Область методу: Зберігає інформацію на рівні класу, як-от назву класу, змінні методів батьківського класу та статичні дані. Спільне використання через JVM.
- Площа купи: Зберігає всі предмети. Спільне використання через JVM.
- Площа стека: Кожен потік має власний стек часу виконання; зберігає виклики методу локальних змінних у кадрах стека. Знищується, коли нитка закінчується.
- Реєстри ПК: Зберігайте адресу поточної інструкції для кожного потоку.
- Стеки рідних методів: Кожен потік має окремий стек для виконання рідного методу.
3. Механізм виконання
Механізм виконання виконує .class (байт-код). Він зчитує байт-код рядок за рядком, використовує дані та інформацію, наявну в різних областях пам’яті, і виконує інструкції. Його можна класифікувати на три частини:
- Перекладач: Він інтерпретує байт-код рядок за рядком, а потім виконує. Недоліком тут є те, що коли один метод викликається кілька разів, кожен раз потрібна інтерпретація.
- Компілятор Just-In-Time (JIT): Використовується для підвищення ефективності перекладача. Він компілює весь байт-код і змінює його на власний код, тому щоразу, коли інтерпретатор бачить повторювані виклики методів, JIT надає прямий власний код для цієї частини, тому повторна інтерпретація не потрібна, що підвищує ефективність.
- Збирач сміття: Він знищує об’єкти, на які немає посилань. Докладніше про Garbage Collector див Збирач сміття .
4. Рідний інтерфейс Java (JNI)
Це інтерфейс, який взаємодіє з бібліотеками рідних методів і надає власні бібліотеки (C C++), необхідні для виконання. Це дозволяє JVM викликати бібліотеки C/C++ і викликати бібліотеки C/C++, які можуть бути специфічними для апаратного забезпечення.
5. Бібліотеки рідних методів
Це колекції нативних бібліотек, необхідних для виконання нативних методів. Вони містять бібліотеки, написані такими мовами, як C і C++.