- Class Loader Subsystem
- Завантаження
- посилання
- Три основні завантажувача класів (cloass loaders):
- пам'ять JVM
- Движок виконання (Execution Engine)
- Java Native Interface (JNI)
- Native Method Libraries
Наша взаимовыгодная связь https://banwar.org/
JVM (Java Virtual Machine) це середовище для запуску Java додатків. При запуску Java програми викликається метод main, який реалізований в java коді. JVM це частина JRE (Java Runtime Environment).
JRE це середовище для запуску Java додатків, не плутати з JDK. JDK (Java Development Kit - це набір інструментів, що дозволяє розробляти додатки на Java, що включає в себе як JRE так компілятор Java коду і бібліотеки для розробки Java додатків).
Java додатки називаються WORA (Write Once Run Everywhere) додатками, тобто буквально напиши один раз і запускай скрізь. Це означає що розробник може створити Java код на одній операційній системі і запустити його в іншій системі, в якій встановлена JRE без будь-яких додаткових налаштувань. Це все можливо тому що це JVM.
Коли ми компілюємо .java файл, створюється .class файл (java byte code) з такою ж назвою, цей файл генерується Java компілятором.
Class Loader Subsystem
В основному відповідає за ці три активності:
- Завантаження
- посилання
- ініціалізація
Завантаження
Завантажувач класів (Class loader) зчитує .class файл, генерує відповідні бінарні дані і зберігає це в області методів.
Для кожного .class файлу, JVM зберігає таку інформацію в області методів:
- Повне ім'я завантажуваного класу і його безпосередні батьківські класи.
- Визначає чи .class файл Java класом, інтерфейсом або Enum.
- Визначає поля, змінні і інформацію про методи і т.д.
Після завантаження .class файлу, JVM створює об'єкти класу в області Heap пам'яті. Необхідно пам'ятати що цей об'єкт є типом Class, який визначений в пакеті java.lang. Об'єкт цього класу програміст може використовувати для отримання інформація рівня класу, наприклад, ім'я класу, ім'я батьківського класу, методи класу, змінні і так далі. Щоб отримати всі ці дані необхідно викликати метод getClass () у цього об'єкта.
// A Java program to demonstrate working of a Class type // object created by JVM to represent .class file in // memory. import java.lang.reflect.Field; import java.lang.reflect.Method; // Java code to demonstrate use of Class object // created by JVM public class Test {public static void main (String [] args) {Student s1 = new Student (); // Getting hold of Class object created // by JVM. Class c1 = s1. getClass (); // Printing type of object using c1. System. out. println (c1. getName ()); // getting all methods in an array Method m [] = c1. getDeclaredMethods (); for (Method method: m) System. out. println (method. getName ()); // getting all fields in an array Field f [] = c1. getDeclaredFields (); for (Field field: f) System. out. println (field. getName ()); }} // A sample class whose information is fetched above using // its Class object. class Student {private String name; private int roll_No; public String getName () {return name; } Public void setName (String name) {this. name = name; } Public int getRoll_no () {return roll_No; } Public void setRoll_no (int roll_no) {this. roll_No = roll_no; }}
Результат виконання даної програми:
Student getName setName getRoll_no setRoll_no name roll_No
Замітка: Для кожного завантаженого класу (.class), створюється тільки один об'єкт.
посилання
Забезпечує перевірку, підготовку і (опціонально) дозвіл.
Перевірка: Чи гарантує коректність .class файлів. Перевіряє що конкретний .class було скомпільовано і згенерований дійсним компілятором. Якщо перевірка не пройдена, то виникає run-time exception java.lang.VerifyError. Підготовка: JVM виділяє пам'ять для змінних класу і ініціалізує ці змінні в пам'яті значеннями за замовчуванням.
Рішення: Цей процес замінює символічні посилання на клас прямими. При пошуку в області методів виявляє залежні сутності класу. Ініціалізація: У цій фазі, все статичні змінні инициализируются заданими значеннями в коді, так само виконуються статичні блоки, якщо такі є. Виконання програми відбувається зверху вниз, в класі і так само від батька до спадкоємця в ієрархії класів.
Три основні завантажувача класів (cloass loaders):
- Bootstrap class loader: Кожна реалізація JVM повинна мати bootstrap class loader, здатна завантажувати перевірені класи. Завантажується основне API Java класів, яке знаходиться в директорії JAVA_HOME / jre / lib. Цей шлях так само називають bootstrap path. Завантажувач реалізований на мовах C, C ++.
- Extension class loader: Це дочірній загрзчік bootstrap class loader. Він завантажує класи, які представлені в дірекотріі JAVA_HOME / jre / lib / ext (Extension path) або в будь-який інший директорії, яка описана в системній змінній java.ext.dirs. Це функція реалізована за допомогою Java sun.misc.Launcher $ ExtClassLoader class
- System / Application class loader: В свою чергу це дочірній завантажувач extension class loader. Завантажує класи з галузі застосування (application classpath). Так само реалізований за допомогою Java sun.misc.Launcher $ ExtClassLoader class.
// Java code to demonstrate Class Loader subsystem public class Test {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 (Test. class. getClassLoader ()); }}
Результат виконання програми:
bash null sun.misc.Launcher$AppClassLoader@73d16e93
Замітка: JVM слід принципу ієрархічного делегування при завантаженні класів. Система завантажувача класів делегує запит в extension class loader, а extension class loader делегує запит в boot-strap classloader. Якщо клас знайдений в boot-strap шляху, то клас завантажується, в іншому випадку запит відправляється назад в extension class loader, а потім в system class loader. І якщо system class loader не зміг завантажити клас, то виникає run-time exception java.lang.ClassNotFoundException.
пам'ять JVM
- Область методів: В області методів, знаходиться вся інформація про клас, наприклад, ім'я класу, імена батьківських класів, методи і змінні, а так само інша інформація, включаючи статичні змінні. Існує лише одна область методів у всій JVM і це область загальний ресурс для всіх програм, що працюють в цій JVM.
- Heap area: Тут зберігається вся інформація про об'єкти. Існує лише одна область Heap в JVM і доступна всім програмам, які працюють в цій JVM.
- Stack area: Для кожного потоку, JVM створює свою область (run-time stack) котоаря зберігається тут. Кожен блок цього стека називається активний запис / вікно стека (activation record / stack frame), В цій області зберігаються виклики методів. Всі локальні змінні цих методів зберігаються в цьому виділеному стеку. Після того як потік завершує свою роботу, виділений стек знищується. Це не загальнодоступний ресурс.
- PC Registers: Зберігає адреси поточних інструкцій потоку. У кожного потоку своя область PC Registers.
- Native method stacks: Для кожного потоку створюється окрема область Native method stacks. У цій області зберігається інформація про нативних методах.
Движок виконання (Execution Engine)
Execution engine виконує байткод .class файлу. Він зчитує байткод послідовно, рядок за рядком, використовує інформацію, яка знаходиться в різних областях пам'яті JVM і виконує інструкції коду. Можна розділити на три складових:
- Інтерпретатор (Interpreter): Інтерпретує байт код в команди і виконує їх. Недолік в тому що кожен раз коли потрібно виконати команду, необхідно інтерпретувати байт код в зрозумілу для JVM команду, навіть якщо викликається один і той же метод кілька разів.
- Just-In-Time Compiler (JIT): Використовується для збільшення ефективності інтерпретатора. Він компілює весь байткод і перетворює його в нативний код, всякий раз коли зустрічає повторювані виклики методів. JIT поставляє нативний код і повторна інтерпретація не потрібна, тому збільшується ефективність.
- Збирач сміття (Garbage Collector): Знищує які не використовуються об'єкти.
Java Native Interface (JNI)
Це інтерфейс для взаємодії з нативними методами системних бібліотек, які можуть бути написані на C, C ++. Для виклику методів з системних бібліотек (наприклад .dll або .so) необхідно вказати де саме це бібліотека знаходиться, щоб JVM знала про цю бібліотеці.
Native Method Libraries
Це набір нативних бібліотек (C, C ++), які необхідні для роботи Execution Engine.
Даний матеріал є переробленим перекладом цієї статті з невеликими доповненнями.