SlideShare a Scribd company logo
JVM: краткий курс
общей анатомии
Никита Липский, Excelsior LLC
Владимир Иванов, Oracle Corp.
2
3
Никита Липский
• Более 20 лет профессиональной карьеры
• Инициатор проекта Excelsior JET
–работал над проектом более 16 лет
–как идейный вдохновитель
–как компиляторный инженер
–как руководитель
–и много в каких еще ролях
• Open source проекты WebFX и Java ReStart
–в свободное от работы время
• Twitter: @pjBooms
4
Владимир Иванов
• Написал первую Java программу в 2002
• С 2005 работает в компании Sun/Oracle
• Инженер HotSpot JVM Compiler
– JIT-компиляторы
– Поддержка динамических языков на JVM
– Работа с платформенным кодом
• Twitter: @iwan0www
5
План доклада
• Java class file and bytecode
• Classloading engine
• Execution engine: interpretators, JIT, AOT
• Meta information access subsystem: reflection, indy, JNI
• Threading, exception handling, synchronization
• Memory management: heap, allocation, GC
• Manageability and Monitoring
6
Java class file & bytecode
7
Java class file
• 1 класс <–> 1 класс-файл
• Constant Pool
– числа, строки
– указатели на классы, методы, поля
• Описание класса
8
– имя
– модификаторы
– супер класс
– супер интерфейсы
– поля
– методы
– атрибуты
Java class file
• Поля, методы тоже имеют атрибуты (например, значения
константных полей)
• Главный атрибут метода – это его код: Java байт-код
9
Java bytecode
• Массив инструкций
• Стэк операндов инструкций метода
• Массив локальных переменных (аргументы метода,
локальные переменные)
10
Java bytecode
Инструкция берет свои операнды со стэка и кладет
результат на стэк. Пример:
11
0: iload 3
2: bipush 5
4: iadd
5: istore 4
7: …
#3
2:I _:?
#4
Java bytecode
Инструкция берет свои операнды со стэка и кладет
результат на стэк. Пример:
12
0: iload 3
2: bipush 5
4: iadd
5: istore 4
7: …
#3
2:I _:?
#4
2:I
Java bytecode
Инструкция берет свои операнды со стэка и кладет
результат на стэк. Пример:
13
0: iload 3
2: bipush 5
4: iadd
5: istore 4
7: …
#3
2:I _:?
#4
2:I
5:I
Java bytecode
Инструкция берет свои операнды со стэка и кладет
результат на стэк. Пример:
14
0: iload 3
2: bipush 5
4: iadd
5: istore 4
7: …
#3
2:I _:?
#4
7:I
Java bytecode
Инструкция берет свои операнды со стэка и кладет
результат на стэк. Пример:
15
0: iload 3
2: bipush 5
4: iadd
5: istore 4
7: …
#3
2:I 7:I
#4
JVM: предисловие
16
Программа для JVM
Любая программа исполняемая на JVM имеет?
17
Программа для JVM
Любая программа исполняемая на JVM имеет:
• main класс
public static void main(String[] args)
• сlasspath – список директорий и архивов (jar файлов)
• В мире веб приложений программа для JVM – это веб сервер
– Tomcat, GlassFish и т.п.
18
Java Runtime
Для исполнения программы на JVM одной JVM не достаточно.
Нужен Java Runtime Environment:
• JVM
• Платформенные классы
– core классы (j.l.Object, j.l.String и т.д.)
– Java standard APIs (IO, NET, NIO, AWT/Swing и т.д)
• Реализация нативных методов платформенных классов (OS
specific)
• Вспомогательные файлы (описатели временных зон, медиа
ресурсы и т.п.)
19
Анатомия JVM
20
OS+CPU
Monitoring
AOT
Bytecode
Classloading
engine
Bytecode Verification
Execution engine:
interpreter, JIT
Threading
Synchronization
Meta
information
Memory management,
Garbage Collection
Native methods
Classloading engine
21
OS+CPU
Monitoring
AOT
Bytecode
Classloading
engine
Bytecode Verification
Execution engine:
interpreter, JIT
Threading
Synchronization
Meta
information
Memory management,
Garbage Collection
Native methods
Загрузка классов
• Где JVM берет классы для исполнения:
– Из Java Runtime (платформенные классы)
– Из classpath приложения
– Авто-сгенеренные на лету (Proxy, Reflection accessors, реализация
invoke dynamic)
– Предоставленные самим приложением
22
Загрузка классов
• Каждый класс грузится каким-то загрузчиком классов:
– Платформенные классы грузятся bootstrap загрузчиком
– Классы из classpath приложения – системным загрузчиком
(AppClassLoader)
– Классы приложения могут создавать свои загрузчики, которые
будут грузить классы
23
Загрузка классов
• Каждый класс грузится каким-то загрузчиком классов:
– Платформенные классы грузятся bootstrap загрузчиком
– Классы из classpath приложения – системным загрузчиком
(AppClassLoader)
– Классы приложения могут создавать свои загрузчики, которые
будут грузить классы
• Загрузчик классов образует уникальное пространство имен
классов
24
Старт JVM
• Грузится main класс системным загрузчиком (из classpath
приложения)
– Провоцирует загрузку части платформенных классов (core)
• Исполняется метод main(String[] args)
25
Процесс загрузки класса
(создание класса)
• Читается class file
– Проверяется корректность формата (может выбросить
ClassFormatError)
• Создается ран-тайм представление класса в выделенной
области памяти
– runtime constant pool in Method Area aka Meta Space aka
Permanent Generation
• Грузятся суперкласс, суперинтерфейсы
26
Линковка
• Верификация байт-кода
• Подготовка
• Разрешение символьных ссылок
27
C: StackOverflowError
A: Программа зациклится B: VerifyError
D: Байт-код не исполнится
Что произойдет при исполнении этого байт-кода?
Верификация байт-кода
• Происходит с классом один раз
• Проверка корректности инструкций (корректности
переходов)
• Проверка выхода за пределы стэка операндов и локальных
переменных
• Проверка совместимости типов
29
Ну а если все-таки запустить без верификации?
$ java –Xverify:none test
# A fatal error has been detected by the Java Runtime Environment:
Exception in thread "main" java.lang.StackOverflowError
at test.foo(test.j)
at test.main(test.j:3)
#
# Internal Error (javaCalls.cpp:53), pid=8012, tid=16396
# guarantee(!thread->is_Compiler_thread()) failed: cannot make java calls from
the compiler
#
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
30
Инициализация класса
• Вызов статического инициализатора класса
• Случается при first use:
– new
– доступ до статического поля
– вызов статического метода
• Провоцирует инициализацию супер-класса и супер-
интерфейсов с default методами
31
Execution engine
32
OS+CPU
Monitoring
Bytecode
Classloading
engine
Execution engine:
interpreter, JIT
Threading
Synchronization
Meta
information
Memory management,
Garbage Collection
Native methods
Bytecode Verification
AOT
Исполнение Java байт-кода
JVM может исполнять байт-код двумя способам:
• Интерпретировать
• Транслировать в машинный код, который будет
исполняться непосредственно на CPU
33
Интерпретатор
pc = 0;
do {
fetch opcode at pc;
if (operands) fetch operands;
execute the opcode;
calculate pc;
} while (there is more to do);
34
Компиляторы
• Неоптимизирующие
– “что вижу, то пою”
• Простые оптимизирующие
– пример: HotSpot Client
• Сложные оптимизирующие
– пример: HotSpot Server
35
• Динамические (Just-In-Time – JIT).
–Трансляция в машинный код происходит во время
исполнения программы
• Статические (Ahead-Of-Time – AOT)
–Трансляция происходит до исполнения программы
36
Компиляторы
Динамические компиляторы (JIT)
• Работают одновременно с исполняемой программой
• Компилируют горячий код
• Горячий код вычисляется с помощью динамического
профилировщика
• Используют информацию времени
исполнения для оптимизаций
37
Статические компиляторы (AOT)
• Не ограничены в ресурсах для оптимизации программ
• Компилируют каждый метод программы применяя самые
агрессивные оптимизации
• На оптимизацию не тратятся ресурсы во время исполнения
программы (быстрее старт)
38
Статические компиляторы (AOT)
Интересный факт:
Во время работы статически скомпилированной Java
программы может не исполниться ни одного Java байт-
кода.
Вопрос: а где JVM?
39
Meta information subsystem
40
OS+CPU
Monitoring
AOT
Bytecode
Classloading
engine
Bytecode Verification
Execution engine:
interpreter, JIT
Threading
Synchronization
Meta
information
Memory management,
Garbage Collection
Native methods
Reflection
• Позволяет доступаться до классов, полей, методов по
имени из Java программы
• Реализуется в JVM через доступ в Meta space
• Ключевая возможность Java для многих популярных
фреймворков и реализаций языков на JVM
41
Method Handles and
invokedynamic (JSR-292, indy)
• Indy: программируемый вызов
– для эффективной реализации динамических языков на JVM
• MethodHandle – целевой объект вызова через
invokedynamic
– может быть доступом к полю, методу
– комбинацией других MethodHandle
– может использоваться отдельно от indy: Reflection 2.0
42
Java native interface (JNI)
• Связывает JVM c внешним миром (OS)
• Си интерфейс к JVM
– Не зависит от реализации JVM
– Используется для реализации native методов на языке С (или другом
системном языке)
– С помощью JNI написаны платформенно-зависимые реализации
Java SE API: IO, NET, AWT
• Реализуется в JVM как доступ к Meta space
43
Threading and synchronization
44
OS+CPU
Monitoring
AOT
Bytecode
Classloading
engine
Bytecode Verification
Execution engine:
interpreter, JIT
Threading
Synchronization
Meta
information
Memory management,
Garbage Collection
Native methods
java.lang.Thread
• Java поток мапируется на нативный поток в соотношение 1-1
• С потоком связана память используемая для локальных
переменных и стэка операндов методов (фреймов методов):
стэк (stack)
– Размер стэка – параметр JVM: -Xss
• Имеет информацию о стэке вызовов методов потока (stack
trace)
– В любой момент может о нем рассказать
45
Обработка исключений
Знание о стэке вызовов помогает в обработке исключений:
46
method 7
throw
method 3
catch
method 6
. . .
method 2
. . .
method 3
catch
method 2
. . .
PC
PC
exception caught
Потоки и Java Memory Model
47
// Thread 1:
Shared.data = getData();
Shared.ready = true;
// Thread 2:
while (!Shared.ready) {
// wait
}
data = Shared.data;
Потоки и Java Memory Model
48
// Thread 1:
Shared.data = getData();
Shared.ready = true;
// Thread 2:
while (!Shared.ready) {
// wait
}
data = Shared.data;
Потоки и Java Memory Model
49
// Thread 1:
Shared.data = getData();
Shared.ready = true;
// Thread 2:
while (!Shared.ready) {
// wait
}
data = Shared.data;
Синхронизация
• Для безопасного доступа к разделяемой памяти между
потоками
• В наивной реализации используются средства ОС
– ОС монитор есть в каждом Java объекте как скрытое поле
• Оптимизирована когда конкуренция за ресурс происходит
много реже, чем вход в synchronized
50
Memory management
51
OS+CPU
Monitoring
AOT
Bytecode
Classloading
engine
Bytecode Verification
Execution engine:
interpreter, JIT
Threading
Synchronization
Meta
information
Memory management,
Garbage Collection
Native methods
Выделение памяти
• Реализация оператора new
• Объекты выделенные с помощью оператора new
располагаются в т.н. куче (Java heap)
• Организация Java heap JVM-cпецифична
• Разметка (layout) Java объекта тоже JVM специфична.
52
Аллокация объектов
• Должна быть быстрой
– JVM запрашивает у OC память не под один объект, а сразу на
много
– Аллокация методом продвижения границы
• Потоко-безопасной (thread-safe), но при этом
параллельной (не блокирующей)
– Thread local heaps: каждый поток “грызет” свой кусок памяти
53
Layout Java объекта
Не специфицируется JVM, но по факту требует:
• Java Object header
– Указатель на класс
– Монитор (lock)
– Identity hashcode
– Флаги для GC
• Поля
– Могут быть переупорядочены из соображений экономии
размера, выравнивания, особенностей целевой архитектуры
54
Сборка мусора
55
Сборка мусора
56
Что такое мусор?
57
Что такое мусор?
58
Что такое мусор?
59
Что такое мусор?
60
Мусор
Мусором являются объекты, которые не могут
использоваться программой
Вопрос: А какие объекты могут использоваться?
61
Мусор
Мусором являются объекты, которые не могут
использоваться программой
Вопрос: А какие объекты могут использоваться?
Ответ: Не мусор!
62
Не мусор
1. Объекты в статических полях классов
2. В локальных переменных
3. … всё?
63
Не мусор
Object o = new Object();
...
64
Не мусор 2
1. Объекты в статических полях классов
2. В локальных переменных
Доступных из фрейма метода (локальные переменные и
стэк операндов)
Какого метода?
65
Не мусор
66
Не мусор 2 возвращается
1. Объекты в статических полях классов
2. В локальных переменных
Доступных из фрейма метода фреймов методов
(локальные переменные и стэк операндов) стэка вызовов
всех Java потоков.
3. Объекты, на которые ссылается “не мусор”
67
Корневое множество объектов
(GC roots)
1. Объекты в статических полях классов
2. Объекты доступные со стэка Java потоков
3. Объекты из JNI ссылок в native методах
68
Не мусор 3
Не мусор aka живые объекты – это:
1. Объекты из корневого множества
2. Объекты, на которые ссылаются живые объекты
Все остальное – мусор.
69
Трассирующие сборщики
• Mark-and-sweep
– Помечает живые объекты (mark), “выметает” (удаляет) мусор
(sweep)
• Stop-and-copy
– Копирует живые объекты в специальное место (copy)
– Освободившиеся место (мусор и места где были живые объекты)
может использоваться для новой аллокации
70
Stop the World
• Живые объекты определены для определенного момента
исполнения программы
– При исполнении множество меняется
• Чтобы собрать мусор в общем случае нужно остановить
потоки, чтобы определить где мусор (STW пауза)
71
Stop the World
Одна из основных задач современных сборщиков мусора –
это уменьшение времени STW паузы. Методы уменьшения:
• Инкрементальный
– собирать не весь мусор в паузе
• Параллельный
– собирать мусор во многих потоках в паузе
• Одновременный (concurrent)
– собирать мусор одновременно с работой программы (не
останавливая потоки)
72
Поколенная сборка мусора
Слабая гипотеза о поколениях:
• большинство объектов умирает молодыми
• старые объекты редко ссылаются на молодые
Поколенный (generational) GC:
• частный вид инкрементального
• во время т.н. малых сборок удаляем мусор среди молодых
объектов
• объекты, пережившие одну или несколько сборок,
перемещаем в область старого поколения
73
Manageability & Monitoring
74
OS+CPU
Monitoring
AOT
Bytecode
Classloading
engine
Bytecode Verification
Execution engine:
interpreter, JIT
Threading
Synchronization
Meta
information
Memory management,
Garbage Collection
Native methods
Manageability & Monitoring
JVM знает про вашу программу всё:
• про все загруженные классы
• про все живые объекты
• про все потоки
• про все исполняемые методы потоков
Почему бы не поделиться с вами этой информацией во время
исполнения?
75
Manageability & Monitoring
JVM Tool Interface (JVM TI):
• отладчики
• профилировщики
Java Management Beans:
• Инструменты мониторинга запущенных приложений
– JConsole, JMX console, AMC
– Visual VM
– Java Mission Control
76
Абстрактная JVM
77
OS+CPU
Monitoring
AOT
Bytecode
Classloading
engine
Bytecode Verification
Execution engine:
interpreter, JIT
Threading
Synchronization
Meta
information
Memory management,
Garbage Collection
Native methods
Реализации JVM
Совместимые с Java SE спецификацией:
• Oracle HotSpot
• Oracle JRockit (RIP)
• IBM J9
• Excelsior JET
• Azul (HotSpot based, но свой GC)
• SAP, RedHat (свои порты HotSpot на разные платформы)
78
Заключение
• JVM сложная, но жутко интересная штука
• Java – золотая середина современных IT технологий:
– Подробно специфицирована
– Эффективность помноженная на гибкость
• Все реализации JVM в постоянном развитии на острие
науки и технологий
79
Вопросы и ответы
Никита Липский,
Excelsior
nlipsky@excelsior-usa.com
twitter: @pjBooms
Владимир Иванов,
Oracle
vladimir.x.ivanov@oracle.com
twitter: @iwan0www
80

More Related Content

PPTX
JVM: краткий курс общей анатомии
PPTX
Java 8 Support at the JVM Level
PPTX
Поддержка Java 8 в Excelsior JET
PDF
Java худеет. Спроси меня как. Уменьшение размера дистрибутива Java приложения...
PPTX
Клиентская Java вне браузера. Делаем нативные клиенты на Java
PPTX
Java 9 Модули. Почему не OSGi?
PPTX
Верификация Java байткода: когда, как, а может отключить?
PPTX
Java Ahead-Of-Time compilation
JVM: краткий курс общей анатомии
Java 8 Support at the JVM Level
Поддержка Java 8 в Excelsior JET
Java худеет. Спроси меня как. Уменьшение размера дистрибутива Java приложения...
Клиентская Java вне браузера. Делаем нативные клиенты на Java
Java 9 Модули. Почему не OSGi?
Верификация Java байткода: когда, как, а может отключить?
Java Ahead-Of-Time compilation

What's hot (20)

PDF
Excelsior JET в действии
PDF
AOT для Java: Мифы и Challenges
PPTX
Java 9 модули
PDF
Разговор про Java 9. Extended version
PDF
What to expect from Java 9
PDF
Tech Talks @NSU: AOT-компиляция Java
PPTX
Статический анализ кода: борьба с удорожанием ошибок
PDF
Java худеет. Спроси меня как.
PDF
Готовимся к Java SE 7 Programmer: от новичка до профессионала за 45 дней
PDF
01 - Java. Введение в Java
PDF
CodeFest 2012. Липский Н. — JIT vs. AOT. Единство и борьба динамического и ст...
PDF
Akka: как я перестал бояться и полюбил асинхронный код
PDF
Scala performance под капотом
PDF
03 - Java. Объекты, классы и пакеты в Java
PDF
09 - Java. Тестирование Java-программ
ODP
Java 9 - Back to the Future
PPTX
Использование Open Source инструментов для автоматизации тестирования
PDF
C++ STL & Qt. Занятие 10.
PDF
"Invokedynamic: роскошь или необходимость?"@ JavaOne Moscow 2013
PPTX
Что могут статические анализаторы, чего не могут программисты и тестировщики
Excelsior JET в действии
AOT для Java: Мифы и Challenges
Java 9 модули
Разговор про Java 9. Extended version
What to expect from Java 9
Tech Talks @NSU: AOT-компиляция Java
Статический анализ кода: борьба с удорожанием ошибок
Java худеет. Спроси меня как.
Готовимся к Java SE 7 Programmer: от новичка до профессионала за 45 дней
01 - Java. Введение в Java
CodeFest 2012. Липский Н. — JIT vs. AOT. Единство и борьба динамического и ст...
Akka: как я перестал бояться и полюбил асинхронный код
Scala performance под капотом
03 - Java. Объекты, классы и пакеты в Java
09 - Java. Тестирование Java-программ
Java 9 - Back to the Future
Использование Open Source инструментов для автоматизации тестирования
C++ STL & Qt. Занятие 10.
"Invokedynamic: роскошь или необходимость?"@ JavaOne Moscow 2013
Что могут статические анализаторы, чего не могут программисты и тестировщики
Ad

Similar to JVM: краткий курс общей анатомии, JPoint 2016 Conference Edition (20)

PDF
15 HappyDev-lite-2015 autumn. Анна Тарасенко. Java в современном мире, вторая...
PPTX
PDF
Java 9: what is there beyond modularization
PPTX
Java Core. Lecture# 1. Intro
PPTX
Lesson 01
PPT
Ввведение в java
PPT
Введение в язык программирования «Java»
ODP
Java: вчера, сегодня, завтра
PPTX
Dz Java Hi Load 0.4
PPTX
Programming Java - Lection 01 - Basics - Lavrentyev Fedor
PPT
0. hello java world
PDF
лекция 01 прогр на java (тсн) - введение в java
PDF
Н. Иготти. Виртуализация и виртуальные машины. Лекция 02
ODP
Java 9 - кратко о новом
PDF
Joker 2016 - Bytecode 101
PDF
Дмитрий Юницкий. «Android NDK или как я перестал бояться и полюбил нативную р...
PDF
Java осень 2013 лекция 1-1
PPTX
Delivering Native User Experience In Client Side Java Applications
PDF
Java весна 2014 лекция 1
PDF
AOT-компиляция Java
15 HappyDev-lite-2015 autumn. Анна Тарасенко. Java в современном мире, вторая...
Java 9: what is there beyond modularization
Java Core. Lecture# 1. Intro
Lesson 01
Ввведение в java
Введение в язык программирования «Java»
Java: вчера, сегодня, завтра
Dz Java Hi Load 0.4
Programming Java - Lection 01 - Basics - Lavrentyev Fedor
0. hello java world
лекция 01 прогр на java (тсн) - введение в java
Н. Иготти. Виртуализация и виртуальные машины. Лекция 02
Java 9 - кратко о новом
Joker 2016 - Bytecode 101
Дмитрий Юницкий. «Android NDK или как я перестал бояться и полюбил нативную р...
Java осень 2013 лекция 1-1
Delivering Native User Experience In Client Side Java Applications
Java весна 2014 лекция 1
AOT-компиляция Java
Ad

More from Nikita Lipsky (10)

PPTX
Escaping The Jar hell with Jigsaw Layers
PDF
JIT Versus AOT: Unity And Conflict of Dynamic and Static Compilers (JavaOne 2...
PPTX
Java 9 Modules: The Duke Yet Lives That OSGi Shall Depose
PPTX
JIT vs. AOT: Unity And Conflict of Dynamic and Static Compilers
PPTX
Ahead-Of-Time Compilation of Java Applications
PPTX
Java Restart with WebFX
PDF
Веб 3.0. Есть ли будущее у Java в RIA и Mobile?
PDF
Занимательные истории из жизни технической поддержки JVM
PPTX
Неумолимая близость десктопа, веба и мобайла
PPT
История одной JVM в картинках
Escaping The Jar hell with Jigsaw Layers
JIT Versus AOT: Unity And Conflict of Dynamic and Static Compilers (JavaOne 2...
Java 9 Modules: The Duke Yet Lives That OSGi Shall Depose
JIT vs. AOT: Unity And Conflict of Dynamic and Static Compilers
Ahead-Of-Time Compilation of Java Applications
Java Restart with WebFX
Веб 3.0. Есть ли будущее у Java в RIA и Mobile?
Занимательные истории из жизни технической поддержки JVM
Неумолимая близость десктопа, веба и мобайла
История одной JVM в картинках

JVM: краткий курс общей анатомии, JPoint 2016 Conference Edition

  • 1. JVM: краткий курс общей анатомии Никита Липский, Excelsior LLC Владимир Иванов, Oracle Corp.
  • 2. 2
  • 3. 3
  • 4. Никита Липский • Более 20 лет профессиональной карьеры • Инициатор проекта Excelsior JET –работал над проектом более 16 лет –как идейный вдохновитель –как компиляторный инженер –как руководитель –и много в каких еще ролях • Open source проекты WebFX и Java ReStart –в свободное от работы время • Twitter: @pjBooms 4
  • 5. Владимир Иванов • Написал первую Java программу в 2002 • С 2005 работает в компании Sun/Oracle • Инженер HotSpot JVM Compiler – JIT-компиляторы – Поддержка динамических языков на JVM – Работа с платформенным кодом • Twitter: @iwan0www 5
  • 6. План доклада • Java class file and bytecode • Classloading engine • Execution engine: interpretators, JIT, AOT • Meta information access subsystem: reflection, indy, JNI • Threading, exception handling, synchronization • Memory management: heap, allocation, GC • Manageability and Monitoring 6
  • 7. Java class file & bytecode 7
  • 8. Java class file • 1 класс <–> 1 класс-файл • Constant Pool – числа, строки – указатели на классы, методы, поля • Описание класса 8 – имя – модификаторы – супер класс – супер интерфейсы – поля – методы – атрибуты
  • 9. Java class file • Поля, методы тоже имеют атрибуты (например, значения константных полей) • Главный атрибут метода – это его код: Java байт-код 9
  • 10. Java bytecode • Массив инструкций • Стэк операндов инструкций метода • Массив локальных переменных (аргументы метода, локальные переменные) 10
  • 11. Java bytecode Инструкция берет свои операнды со стэка и кладет результат на стэк. Пример: 11 0: iload 3 2: bipush 5 4: iadd 5: istore 4 7: … #3 2:I _:? #4
  • 12. Java bytecode Инструкция берет свои операнды со стэка и кладет результат на стэк. Пример: 12 0: iload 3 2: bipush 5 4: iadd 5: istore 4 7: … #3 2:I _:? #4 2:I
  • 13. Java bytecode Инструкция берет свои операнды со стэка и кладет результат на стэк. Пример: 13 0: iload 3 2: bipush 5 4: iadd 5: istore 4 7: … #3 2:I _:? #4 2:I 5:I
  • 14. Java bytecode Инструкция берет свои операнды со стэка и кладет результат на стэк. Пример: 14 0: iload 3 2: bipush 5 4: iadd 5: istore 4 7: … #3 2:I _:? #4 7:I
  • 15. Java bytecode Инструкция берет свои операнды со стэка и кладет результат на стэк. Пример: 15 0: iload 3 2: bipush 5 4: iadd 5: istore 4 7: … #3 2:I 7:I #4
  • 17. Программа для JVM Любая программа исполняемая на JVM имеет? 17
  • 18. Программа для JVM Любая программа исполняемая на JVM имеет: • main класс public static void main(String[] args) • сlasspath – список директорий и архивов (jar файлов) • В мире веб приложений программа для JVM – это веб сервер – Tomcat, GlassFish и т.п. 18
  • 19. Java Runtime Для исполнения программы на JVM одной JVM не достаточно. Нужен Java Runtime Environment: • JVM • Платформенные классы – core классы (j.l.Object, j.l.String и т.д.) – Java standard APIs (IO, NET, NIO, AWT/Swing и т.д) • Реализация нативных методов платформенных классов (OS specific) • Вспомогательные файлы (описатели временных зон, медиа ресурсы и т.п.) 19
  • 20. Анатомия JVM 20 OS+CPU Monitoring AOT Bytecode Classloading engine Bytecode Verification Execution engine: interpreter, JIT Threading Synchronization Meta information Memory management, Garbage Collection Native methods
  • 21. Classloading engine 21 OS+CPU Monitoring AOT Bytecode Classloading engine Bytecode Verification Execution engine: interpreter, JIT Threading Synchronization Meta information Memory management, Garbage Collection Native methods
  • 22. Загрузка классов • Где JVM берет классы для исполнения: – Из Java Runtime (платформенные классы) – Из classpath приложения – Авто-сгенеренные на лету (Proxy, Reflection accessors, реализация invoke dynamic) – Предоставленные самим приложением 22
  • 23. Загрузка классов • Каждый класс грузится каким-то загрузчиком классов: – Платформенные классы грузятся bootstrap загрузчиком – Классы из classpath приложения – системным загрузчиком (AppClassLoader) – Классы приложения могут создавать свои загрузчики, которые будут грузить классы 23
  • 24. Загрузка классов • Каждый класс грузится каким-то загрузчиком классов: – Платформенные классы грузятся bootstrap загрузчиком – Классы из classpath приложения – системным загрузчиком (AppClassLoader) – Классы приложения могут создавать свои загрузчики, которые будут грузить классы • Загрузчик классов образует уникальное пространство имен классов 24
  • 25. Старт JVM • Грузится main класс системным загрузчиком (из classpath приложения) – Провоцирует загрузку части платформенных классов (core) • Исполняется метод main(String[] args) 25
  • 26. Процесс загрузки класса (создание класса) • Читается class file – Проверяется корректность формата (может выбросить ClassFormatError) • Создается ран-тайм представление класса в выделенной области памяти – runtime constant pool in Method Area aka Meta Space aka Permanent Generation • Грузятся суперкласс, суперинтерфейсы 26
  • 27. Линковка • Верификация байт-кода • Подготовка • Разрешение символьных ссылок 27
  • 28. C: StackOverflowError A: Программа зациклится B: VerifyError D: Байт-код не исполнится Что произойдет при исполнении этого байт-кода?
  • 29. Верификация байт-кода • Происходит с классом один раз • Проверка корректности инструкций (корректности переходов) • Проверка выхода за пределы стэка операндов и локальных переменных • Проверка совместимости типов 29
  • 30. Ну а если все-таки запустить без верификации? $ java –Xverify:none test # A fatal error has been detected by the Java Runtime Environment: Exception in thread "main" java.lang.StackOverflowError at test.foo(test.j) at test.main(test.j:3) # # Internal Error (javaCalls.cpp:53), pid=8012, tid=16396 # guarantee(!thread->is_Compiler_thread()) failed: cannot make java calls from the compiler # # If you would like to submit a bug report, please visit: # http://bugreport.java.com/bugreport/crash.jsp 30
  • 31. Инициализация класса • Вызов статического инициализатора класса • Случается при first use: – new – доступ до статического поля – вызов статического метода • Провоцирует инициализацию супер-класса и супер- интерфейсов с default методами 31
  • 32. Execution engine 32 OS+CPU Monitoring Bytecode Classloading engine Execution engine: interpreter, JIT Threading Synchronization Meta information Memory management, Garbage Collection Native methods Bytecode Verification AOT
  • 33. Исполнение Java байт-кода JVM может исполнять байт-код двумя способам: • Интерпретировать • Транслировать в машинный код, который будет исполняться непосредственно на CPU 33
  • 34. Интерпретатор pc = 0; do { fetch opcode at pc; if (operands) fetch operands; execute the opcode; calculate pc; } while (there is more to do); 34
  • 35. Компиляторы • Неоптимизирующие – “что вижу, то пою” • Простые оптимизирующие – пример: HotSpot Client • Сложные оптимизирующие – пример: HotSpot Server 35
  • 36. • Динамические (Just-In-Time – JIT). –Трансляция в машинный код происходит во время исполнения программы • Статические (Ahead-Of-Time – AOT) –Трансляция происходит до исполнения программы 36 Компиляторы
  • 37. Динамические компиляторы (JIT) • Работают одновременно с исполняемой программой • Компилируют горячий код • Горячий код вычисляется с помощью динамического профилировщика • Используют информацию времени исполнения для оптимизаций 37
  • 38. Статические компиляторы (AOT) • Не ограничены в ресурсах для оптимизации программ • Компилируют каждый метод программы применяя самые агрессивные оптимизации • На оптимизацию не тратятся ресурсы во время исполнения программы (быстрее старт) 38
  • 39. Статические компиляторы (AOT) Интересный факт: Во время работы статически скомпилированной Java программы может не исполниться ни одного Java байт- кода. Вопрос: а где JVM? 39
  • 40. Meta information subsystem 40 OS+CPU Monitoring AOT Bytecode Classloading engine Bytecode Verification Execution engine: interpreter, JIT Threading Synchronization Meta information Memory management, Garbage Collection Native methods
  • 41. Reflection • Позволяет доступаться до классов, полей, методов по имени из Java программы • Реализуется в JVM через доступ в Meta space • Ключевая возможность Java для многих популярных фреймворков и реализаций языков на JVM 41
  • 42. Method Handles and invokedynamic (JSR-292, indy) • Indy: программируемый вызов – для эффективной реализации динамических языков на JVM • MethodHandle – целевой объект вызова через invokedynamic – может быть доступом к полю, методу – комбинацией других MethodHandle – может использоваться отдельно от indy: Reflection 2.0 42
  • 43. Java native interface (JNI) • Связывает JVM c внешним миром (OS) • Си интерфейс к JVM – Не зависит от реализации JVM – Используется для реализации native методов на языке С (или другом системном языке) – С помощью JNI написаны платформенно-зависимые реализации Java SE API: IO, NET, AWT • Реализуется в JVM как доступ к Meta space 43
  • 44. Threading and synchronization 44 OS+CPU Monitoring AOT Bytecode Classloading engine Bytecode Verification Execution engine: interpreter, JIT Threading Synchronization Meta information Memory management, Garbage Collection Native methods
  • 45. java.lang.Thread • Java поток мапируется на нативный поток в соотношение 1-1 • С потоком связана память используемая для локальных переменных и стэка операндов методов (фреймов методов): стэк (stack) – Размер стэка – параметр JVM: -Xss • Имеет информацию о стэке вызовов методов потока (stack trace) – В любой момент может о нем рассказать 45
  • 46. Обработка исключений Знание о стэке вызовов помогает в обработке исключений: 46 method 7 throw method 3 catch method 6 . . . method 2 . . . method 3 catch method 2 . . . PC PC exception caught
  • 47. Потоки и Java Memory Model 47 // Thread 1: Shared.data = getData(); Shared.ready = true; // Thread 2: while (!Shared.ready) { // wait } data = Shared.data;
  • 48. Потоки и Java Memory Model 48 // Thread 1: Shared.data = getData(); Shared.ready = true; // Thread 2: while (!Shared.ready) { // wait } data = Shared.data;
  • 49. Потоки и Java Memory Model 49 // Thread 1: Shared.data = getData(); Shared.ready = true; // Thread 2: while (!Shared.ready) { // wait } data = Shared.data;
  • 50. Синхронизация • Для безопасного доступа к разделяемой памяти между потоками • В наивной реализации используются средства ОС – ОС монитор есть в каждом Java объекте как скрытое поле • Оптимизирована когда конкуренция за ресурс происходит много реже, чем вход в synchronized 50
  • 51. Memory management 51 OS+CPU Monitoring AOT Bytecode Classloading engine Bytecode Verification Execution engine: interpreter, JIT Threading Synchronization Meta information Memory management, Garbage Collection Native methods
  • 52. Выделение памяти • Реализация оператора new • Объекты выделенные с помощью оператора new располагаются в т.н. куче (Java heap) • Организация Java heap JVM-cпецифична • Разметка (layout) Java объекта тоже JVM специфична. 52
  • 53. Аллокация объектов • Должна быть быстрой – JVM запрашивает у OC память не под один объект, а сразу на много – Аллокация методом продвижения границы • Потоко-безопасной (thread-safe), но при этом параллельной (не блокирующей) – Thread local heaps: каждый поток “грызет” свой кусок памяти 53
  • 54. Layout Java объекта Не специфицируется JVM, но по факту требует: • Java Object header – Указатель на класс – Монитор (lock) – Identity hashcode – Флаги для GC • Поля – Могут быть переупорядочены из соображений экономии размера, выравнивания, особенностей целевой архитектуры 54
  • 61. Мусор Мусором являются объекты, которые не могут использоваться программой Вопрос: А какие объекты могут использоваться? 61
  • 62. Мусор Мусором являются объекты, которые не могут использоваться программой Вопрос: А какие объекты могут использоваться? Ответ: Не мусор! 62
  • 63. Не мусор 1. Объекты в статических полях классов 2. В локальных переменных 3. … всё? 63
  • 64. Не мусор Object o = new Object(); ... 64
  • 65. Не мусор 2 1. Объекты в статических полях классов 2. В локальных переменных Доступных из фрейма метода (локальные переменные и стэк операндов) Какого метода? 65
  • 67. Не мусор 2 возвращается 1. Объекты в статических полях классов 2. В локальных переменных Доступных из фрейма метода фреймов методов (локальные переменные и стэк операндов) стэка вызовов всех Java потоков. 3. Объекты, на которые ссылается “не мусор” 67
  • 68. Корневое множество объектов (GC roots) 1. Объекты в статических полях классов 2. Объекты доступные со стэка Java потоков 3. Объекты из JNI ссылок в native методах 68
  • 69. Не мусор 3 Не мусор aka живые объекты – это: 1. Объекты из корневого множества 2. Объекты, на которые ссылаются живые объекты Все остальное – мусор. 69
  • 70. Трассирующие сборщики • Mark-and-sweep – Помечает живые объекты (mark), “выметает” (удаляет) мусор (sweep) • Stop-and-copy – Копирует живые объекты в специальное место (copy) – Освободившиеся место (мусор и места где были живые объекты) может использоваться для новой аллокации 70
  • 71. Stop the World • Живые объекты определены для определенного момента исполнения программы – При исполнении множество меняется • Чтобы собрать мусор в общем случае нужно остановить потоки, чтобы определить где мусор (STW пауза) 71
  • 72. Stop the World Одна из основных задач современных сборщиков мусора – это уменьшение времени STW паузы. Методы уменьшения: • Инкрементальный – собирать не весь мусор в паузе • Параллельный – собирать мусор во многих потоках в паузе • Одновременный (concurrent) – собирать мусор одновременно с работой программы (не останавливая потоки) 72
  • 73. Поколенная сборка мусора Слабая гипотеза о поколениях: • большинство объектов умирает молодыми • старые объекты редко ссылаются на молодые Поколенный (generational) GC: • частный вид инкрементального • во время т.н. малых сборок удаляем мусор среди молодых объектов • объекты, пережившие одну или несколько сборок, перемещаем в область старого поколения 73
  • 74. Manageability & Monitoring 74 OS+CPU Monitoring AOT Bytecode Classloading engine Bytecode Verification Execution engine: interpreter, JIT Threading Synchronization Meta information Memory management, Garbage Collection Native methods
  • 75. Manageability & Monitoring JVM знает про вашу программу всё: • про все загруженные классы • про все живые объекты • про все потоки • про все исполняемые методы потоков Почему бы не поделиться с вами этой информацией во время исполнения? 75
  • 76. Manageability & Monitoring JVM Tool Interface (JVM TI): • отладчики • профилировщики Java Management Beans: • Инструменты мониторинга запущенных приложений – JConsole, JMX console, AMC – Visual VM – Java Mission Control 76
  • 77. Абстрактная JVM 77 OS+CPU Monitoring AOT Bytecode Classloading engine Bytecode Verification Execution engine: interpreter, JIT Threading Synchronization Meta information Memory management, Garbage Collection Native methods
  • 78. Реализации JVM Совместимые с Java SE спецификацией: • Oracle HotSpot • Oracle JRockit (RIP) • IBM J9 • Excelsior JET • Azul (HotSpot based, но свой GC) • SAP, RedHat (свои порты HotSpot на разные платформы) 78
  • 79. Заключение • JVM сложная, но жутко интересная штука • Java – золотая середина современных IT технологий: – Подробно специфицирована – Эффективность помноженная на гибкость • Все реализации JVM в постоянном развитии на острие науки и технологий 79
  • 80. Вопросы и ответы Никита Липский, Excelsior [email protected] twitter: @pjBooms Владимир Иванов, Oracle [email protected] twitter: @iwan0www 80