Skip to content

Instantly share code, notes, and snippets.

@vchernogorov
Last active January 8, 2023 19:49
Show Gist options
  • Save vchernogorov/b13fd9f96ab3148e60e520b5fc6d9c1b to your computer and use it in GitHub Desktop.
Save vchernogorov/b13fd9f96ab3148e60e520b5fc6d9c1b to your computer and use it in GitHub Desktop.
Java Advanced

Жизненный цикл Java приложения

Компонент, который стартует HotSpot VM называется лаунчером (launcher). Существует несколько HotSpot VM лаунчеров. Самый распространенный - это лаунчер командной строки java и javaw. Также существует сетевой лаунчер javaws, который испольуется браузерами для запуска апплетов (applet). JNI (Java Native Interface) - фреймворк, позволяющий нативным приложениям вызывать джава методы из существующей JVM по средством структуры JNIEnv. Она содержит все необходимые функции для работы с JVM и джава объектами. Т.е. можно сказать, что все, что можно написать с помощью джава кода, можно выполнить с помощью JNIEnv.

Старт приложения

  1. Парсинг параметров командной строки. Некоторые параметры служат сигналом для самом лаунчера (такие как -client или -server), а некоторые перенаправляются для HotSpot VM.
  2. Установка размеров хипа (heap) и типа JIT компилятора (если какой либо из параметров -client или -server не был указан, то тип JIT компилятора выбирается неявно самим лаунчером).
  3. Установка переменных среды (environment variables), таких как LD_LIBRARY_PATH и CLASSPATH.
  4. Если мейн класс (Main-Class) не был передан в параметрах, то лаунчер пытается его достать из манифест (manifest) файла запускаемой джарки (JAR). (мейн класс содержит в себе точку входа - public static void main(String[] args))
  5. Создание HotSpot VM путем вызова метода JNI_CreateJavaVM.
    • Гарантируется, что только один поток вызывает этот метод и только одна виртуальная машина будет создана.
    • Проверки JNI и инициализации потока вывода для логгирования сборщика мусора.
    • Инициализация модулей операционной системы, таких как генератор рандомных чисел, guard pages (динамическое управление памятью), ID текущего процесса и др.
    • Передаются распаршенные аргументы из командной строки в JNI_CreateJavaVM для дальнейшего использования.
    • Инициализируются системныe Java проперти (такие как java.version или java.vendor), модули поддержки синхронизации, стека, памяти, необходимые библиотеки (libzip, libhpi, libjava и libthread), поток вывода, локальное хранилище потока и его состояния и т.д.
    • После всех этих инициализаций HotSpot VM уже может создавать потоки. Главный поток приложения присоединен к потоку операционный системы, но он еще должен быть добавлен в список "разрешенных" потоков.
    • Происходит еще кучка инициализаций: bootclassloader, кеширование кода, интерпритатор, JIT компилятор, JNI и др.
    • На данном этапе главный поток добавлен в список "разрешенных" потоков, VMThread виртуальной машины, который выполняет главные функции HotSpot VM, тоже проинициализирован.
    • Загружаются различные системные джава классы (java.lang.String, java.lang.System, java.lang.Thread, java.lang.ThreadGroup, java.lang.reflect.Method, java.lang.ref.Finalizer, java.lang.Class). HotSpot VM проинициализирована и почти готова к работе.
    • После того, как JIT компилятор проинициализировался, стартанули все нужные вспомогательные потоки для HotSpot VM, витуальная машина готова к работе.
    • Теперь HotSpot VM готова к обработке JNI реквестов.
  6. Как только HotSpot VM проинициализированна, ищется главный класс, который содержит public static void main.
  7. Далее HotSpot VM производит вызов метода main, используя метод CallStaticVoidMethod и передавая ему распаршенные аргументы из командной строки, полученные на шаге 5.5.

Примерный порядок инициализации приложения

Ниже представлена примерная реализация приложения, подробную инициализацию HotSpot VM для JDK7 можно посмотреть здесь.

#include <jni.h>       /* where everything is defined */
...
JavaVM *jvm;       /* denotes a Java VM */
JNIEnv *env;       /* pointer to native method interface */
JavaVMInitArgs vm_args; /* JDK/JRE 6 VM initialization arguments */
JavaVMOption* options = new JavaVMOption[1];
options[0].optionString = "-Djava.class.path=/usr/lib/java";
vm_args.version = JNI_VERSION_1_6;
vm_args.nOptions = 1;
vm_args.options = options;
vm_args.ignoreUnrecognized = false;
/* load and initialize a Java VM, return a JNI interface pointer in env */
JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
delete options;
/* invoke the Main.test method using the JNI */
jclass cls = env->FindClass("Main");
jmethodID mid = env->GetStaticMethodID(cls, "test", "(I)V");
env->CallStaticVoidMethod(cls, mid, 100);
/* We are done. */
jvm->DestroyJavaVM();

Сборщик мусора Java

Терминология сборщиков

Garbage collector (GC) - сборщик мусора в JVM, который освобождает память от неиспользуемых объектов.

Concurrent collector - сборщик, который работает параллельно с работой приложения.

Parallel collector - сборщик, который использует несколько CPU.

Stop-the-World (STW) collector - сборщик, который работает во время полной остановки приложения.

Incremental collector - сборщик, который выполняет дискретные операции с большим промежутком времени.

Conservative collector - сборщик называется неточным, если он не знает обо всех ссылках объекта во время его сборки или не уверен ссылочного типа данное поле или нет.

Precise collector - сборщик называется точным, если он может точно идентифицировать и обработать все ссылки объекта во время сборки.

  • Сборщик обязан быть точным, чтобы двигать объекты
  • Компиляторы должны предоставлять подробную OopMap для точных сборщиков
  • Все коммерческие серверные JVM должны использовать точный сборщик

Safepoints

Safepoint или GC Safepoint - это точка или отрезок в выполнении потока, где сборщик может идентифицировать все указатели в стеке этого потока.

  • Существуют также и другие типы сейвпоинтов, включая те, что требуют больше информации, чем GS сейвпоинт (например, для оптимизации).
  • Когда поток достигает сейвпоинта, он не может выполниться "мимо" него.
  • Существует "глобальный сейвпоинт", в котором все потоки будут задействованы.
  • Сейвпоинты должны быть каждые несколько микросекунд выполнения потока.
  • Все блокирующие операции сборщика мусора выполняются во время сейвпонтов.

Точный сборщик мусора (Precise GC)

Основные и необходимые механизмы точного сборщика мусора:

  • Идентификация "живых" (использующихся) объектов в хипе.
  • Освобождение ресурсов, занятых "мертыми" (неиспользующимися) объектами.
  • Периодическое перемещение живых объектов.

[1] https://www.youtube.com/watch?v=we_enrM7TSY&t=3923s

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment