correction and addition
This commit is contained in:
parent
b104848ea1
commit
cca6a5a73a
102
jvm.md
102
jvm.md
|
@ -1,21 +1,16 @@
|
|||
###### JVM (Java Virtual Machine)
|
||||
|
||||
Виртуальная машина Java (JVM) - это механизм, обеспечивающий среду выполнения для управления Java-кодом или приложениями.
|
||||
Виртуальная машина является независимой оболочкой исполнения кода, благодаря которой возможен запуск на любой ОС,
|
||||
Виртуальная машина Java (JVM) - это механизм, предоставляющий среду выполнения для управления Java-кодом или приложениями.
|
||||
Виртуальная машина является независимой оболочкой исполнения кода, благодаря которой возможен её запуск на любой ОС,
|
||||
без влияния ОС на выполняемую программу.
|
||||
|
||||
За что отвечает JVM:
|
||||
1. Загрузка, проверка (верификация) и исполнение байт кода;
|
||||
2. Предоставление среды выполнения для выполнения байт-кода;
|
||||
3. Управление памятью и очисткой мусора (Garbage collection);
|
||||
|
||||
JVM работает с 2мя типами данных: примитивные типы (**primitive types**) и ссылочные типы (**reference types**).
|
||||
|
||||
**Примитивы**
|
||||
|
||||
JVM работает с примитивными значениями (целыми числами и числами с плавающей точкой) и ссылками. По сути, JVM - это 32-битная машина.
|
||||
Типы `long` и `double`, которые являются 64-битными, поддерживаются изначально,
|
||||
но занимают две единицы памяти в `frame's local` или стеке операндов, поскольку каждая единица составляет 32 бита.
|
||||
JVM работает с примитивными значениями (целыми числами и числами с плавающей точкой). По сути, JVM - это 32-битная машина.
|
||||
Типы `long` и `double`, которые являются 64-битными, поддерживаются изначально, но занимают две единицы памяти в `frame's local`
|
||||
или стеке операндов, поскольку каждая единица составляет 32 бита.
|
||||
Типы `boolean`, `byte`, `short` и `char` имеют расширенный знак (кроме `char` с нулевым расширением) и работают как 32-разрядные целые числа, так же как и типы `int`.
|
||||
Меньшие типы имеют только несколько специфических для типа инструкций для загрузки, хранения и преобразования типов.
|
||||
`boolean` значение работает как 8-битное `byte` значения, где 0 представляет значение **false**, а 1 - значение **true**.
|
||||
|
@ -31,6 +26,11 @@ JVM работает с примитивными значениями (целы
|
|||
которые реализуют интерфейсы соответственно.
|
||||
|
||||
|
||||
За что отвечает JVM:
|
||||
1. Загрузка, проверка (верификация) и исполнение байт кода;
|
||||
2. Предоставление среды выполнения для выполнения байт-кода;
|
||||
3. Управление памятью и очисткой мусора (Garbage collection);
|
||||
|
||||
![JVM Architecture]
|
||||
(jvmarchitecture.png)
|
||||
|
||||
|
@ -73,7 +73,7 @@ Java Classloader является частью JRE, которая динами
|
|||
* изменить способ загрузки байт-кода (например, можно использовать зашифрованный байт-код класса Java);
|
||||
* модифицировать загруженный байт-код (например, для переплетения аспектов во время загрузки при использовании аспектно-ориентированного программирования);
|
||||
|
||||
Загрузчик классов выполняет три основных действия в этом строгом порядке:
|
||||
Загрузчик классов выполняет три основных действия в строгом порядке:
|
||||
* Загрузка: находит и импортирует двоичные данные для типа.
|
||||
* Связывание: выполняет проверку, подготовку и (необязательно) разрешение.
|
||||
- Проверка: обеспечивает правильность импортируемого типа.
|
||||
|
@ -86,36 +86,33 @@ Java Classloader является частью JRE, которая динами
|
|||
JVM выделяет множество областей данных во время выполнения, к-рые используются во время выполнения программы. Некоторые участки данных
|
||||
созданы JVM во время старта и уничтожаются во время её выключения. Другие создаются для каждого потока и уничтожаются когда поток уничтожается.
|
||||
|
||||
2.1. The pc Register
|
||||
2.1. The pc Register (PCR)
|
||||
|
||||
Виртуальная машина Java может поддерживать много потоков исполнения одновременно. Каждый поток виртуальной машины Java имеет свой собственный регистр PC (programm counter).
|
||||
В любой момент каждый поток виртуальной машины Java выполняет код одного метода, а именно текущий метод для этого потока.
|
||||
Если этот метод не является native, регистр pc содержит адрес инструкции виртуальной машины Java, выполняемой в настоящее время.
|
||||
Коротко говоря: для одного потока существует один PCR, который создается при запуске потока. PCR хранит адрес выполняемой сейчас инструкции JVM.
|
||||
|
||||
2.2. Java Virtual Machine Stacks
|
||||
|
||||
Каждый поток виртуальной машины Java имеет собственный стек виртуальной машины Java, созданный одновременно с потоком.
|
||||
Стек виртуальной машины Java хранит frames. Cтеки виртуальных машин Java могут иметь фиксированный размер
|
||||
или динамически расширяться и сжиматься в соответствии с требованиями вычислений.
|
||||
Каждый поток в JVM имеет собственный стек, созданный одновременно с потоком. Стек в JVM хранит frames.
|
||||
Cтеки в JVM могут иметь фиксированный размер или динамически расширяться и сжиматься в соответствии с требованиями вычислений.
|
||||
|
||||
2.3. Heap
|
||||
|
||||
Виртуальная машина Java имеет кучу, которая используется всеми потоками виртуальной машины Java.
|
||||
JVM имеет heap (кучу), которая используется всеми потоками виртуальной машины Java.
|
||||
Куча - это область данных времени выполнения, из которой выделяется память для всех экземпляров и массивов классов.
|
||||
Куча создается при запуске виртуальной машины. Хранилище для объектов восстанавливается автоматической системой
|
||||
управления данными (известной как сборщик мусора); объекты никогда не освобождаются явно.
|
||||
Виртуальная машина Java не предполагает какого-либо конкретного типа системы автоматического управления хранением данных,
|
||||
JVM не предполагает какого-либо конкретного типа системы автоматического управления хранением данных,
|
||||
и метод управления может быть выбран в соответствии с системными требованиями разработчика.
|
||||
Куча может иметь фиксированный размер или может быть расширена в соответствии с требованиями вычислений и может быть сокращена,
|
||||
если большая куча становится ненужной. Память для кучи не должна быть смежной.
|
||||
|
||||
2.4. Method Area
|
||||
|
||||
Виртуальная машина Java имеет область методов, которая является общей для всех потоков виртуальной машины Java.
|
||||
Область метода аналогична области хранения скомпилированного кода на традиционном языке или аналогична сегменту «текст» в процессе операционной системы.
|
||||
Он хранит структуры для каждого класса, такие как пул постоянных времени выполнения, данные полей и методов,
|
||||
JVM имеет область методов, которая является общей для всех потоков. Он хранит структуры для каждого класса, такие как пул констант, данные полей и методов,
|
||||
а также код для методов и конструкторов, включая специальные методы, используемые при инициализации классов и экземпляров и инициализации интерфейса.
|
||||
|
||||
Хотя область метода является логически частью кучи, простые реализации могут не обрабатываться собиращиком мусора. Область метода может иметь
|
||||
фиксированный размер или может быть расширена в соответствии с требованиями вычислений и может быть сокращена, если большая область метода становится ненужной.
|
||||
|
||||
|
@ -129,21 +126,76 @@ JVM выделяет множество областей данных во вр
|
|||
|
||||
2.6. Native Method Stacks
|
||||
|
||||
Реализация виртуальной машины Java может использовать обычные стеки, обычно называемые «стеки С», для поддержки native methods (методов, написанных на языке, отличном от языка программирования Java).
|
||||
Реализация виртуальной машины Java может использовать обычные стеки, обычно называемые «стеки Си», для поддержки native methods (методов, написанных на языке, отличном от языка программирования Java).
|
||||
|
||||
|
||||
###### 3. Frames
|
||||
|
||||
Frame используется для хранения данных и частичных результатов, а также для выполнения динамического связывания, возврата значений для методов и отправки исключений.
|
||||
Новый frame создается каждый раз, когда вызывается метод. Frame уничтожается, когда завершается его вызов метода,
|
||||
Новый frame создается каждый раз, когда вызывается метод. Frame уничтожается, когда завершается вызов метода,
|
||||
является ли это завершение нормальным или резким (он генерирует неперехваченное исключение). Frames выделяются из стека потока, создающего frame.
|
||||
Каждый frame имеет свой собственный массив локальных переменных, свой собственный стек операндов и ссылку на пул констант во время выполнения класса текущего метода.
|
||||
Размеры массива локальных переменных и стека операндов определяются во время компиляции и предоставляются вместе с кодом для метода, связанного с фреймом.
|
||||
Таким образом, размер структуры данных frame-а зависит только от реализации виртуальной машины Java, и память для этих структур может быть выделена одновременно при вызове метода.
|
||||
|
||||
Только один frame, frame для метода выполнения, активен в любой точке данного потока управления. Этот кадр называется текущим frame, а его метод известен как текущий метод.
|
||||
Только один frame активен в любой точке данного потока управления - метода выполнения, и это frame называется текущим, а его метод известен как текущий метод.
|
||||
Класс, в котором определен текущий метод, является текущим классом. Операции над локальными переменными и стеком операндов обычно выполняются со ссылкой на текущий frame.
|
||||
|
||||
Frame перестает быть текущим, если его метод вызывает другой метод или если его метод завершается. Когда метод вызывается, новый frame создается и становится текущим,
|
||||
когда управление переходит к новому методу. При возврате метода текущий frame передает результат вызова метода, если таковой имеется, в предыдущий frame.
|
||||
Текущий frame затем отбрасывается, так как предыдущий frame становится текущим. Обратите внимание, что frame, созданный потоком, является локальным для этого потока и на него не может ссылаться ни один другой поток.
|
||||
Текущий frame затем отбрасывается, так как предыдущий frame становится текущим. Обратите внимание, что frame, созданный потоком,
|
||||
является локальным для этого потока и на него не может ссылаться ни один другой поток.
|
||||
|
||||
3.1. Локальные переменные
|
||||
|
||||
Каждый frame содержит массив переменных, известных как его локальные переменные. Длина массива локальных переменных frame определяется во время компиляции
|
||||
и предоставляется в двоичном представлении класса или интерфейса вместе с кодом для метода, связанного с frame-ом.
|
||||
Еденичная локальная переменная может хранить значение типа: boolean, byte, char, short, int, float, reference, or returnAddress.
|
||||
Пара локальных переменных может хранить сначение типов: long или double.
|
||||
|
||||
Локальные переменные адресуются путем индексации. Индекс первой локальной переменной равен нулю.
|
||||
|
||||
Значение типа long или типа double занимает две последовательные локальные переменные.
|
||||
|
||||
JVM использует локальные переменные для передачи параметров при вызове метода. При вызове метода класса все параметры передаются в последовательных локальных переменных,
|
||||
начиная с локальной переменной 0. При вызове метода экземпляра локальная переменная 0 всегда используется для передачи ссылки на объект,
|
||||
для которого вызывается метод экземпляра (this в Java). Любые параметры впоследствии передаются в последовательных локальных переменных, начиная с локальной переменной 1.
|
||||
|
||||
3.2. Стеки операндов (Operand Stacks)
|
||||
|
||||
Каждый frame содержит стек «последний вошел - первый вышел» (LIFO), известный как стек операндов. Максимальная глубина стека операндов frame-a
|
||||
определяется во время компиляции и предоставляется вместе с кодом для метода, связанного с frame-ом.
|
||||
|
||||
Стек операнда пуст при создании frame-a, который его содержит. JVM предоставляет инструкции для загрузки констант
|
||||
или значений из локальных переменных или полей в стек операндов. Другие инструкции JVM берут операнды из стека операндов,
|
||||
оперируют с ними и помещают результат обратно в стек операндов. Стек операндов также используется для подготовки параметров
|
||||
для передачи в методы и для получения результатов метода.
|
||||
|
||||
Для примера, инструкция **iadd** суммирует два int-вых значения. От стека операндов требуется, чтобы два int-вых значения были наверху стека.
|
||||
Значения удаляются из стека, операция **pop**. Суммируются и их сумма помещается в стек операндов.
|
||||
|
||||
3.3. Динамическое связывание (Dynamic Linking)
|
||||
|
||||
Каждый frame содержит ссылку на run-time constant pool (2.5) для типа текущего метода для поддержки динамического связывания кода метода.
|
||||
Доступ к вызываемым методам и переменным осуществляется через символические ссылки из class файла.
|
||||
Динамическое связывание преобразует эти символьные ссылки на методы в конкретные ссылки на методы, загружая классы по мере необходимости
|
||||
для разрешения пока еще не определенных символов, и преобразует обращения к переменным в соответствующие смещения в структурах хранения,
|
||||
связанных с расположением этих переменных во время выполнения.
|
||||
|
||||
Позднее связывание методов и переменных вносит изменения в другие классы, которые метод использует с меньшей вероятностью нарушить этот код.
|
||||
|
||||
3.5. Нормальное завершение вызова метода
|
||||
|
||||
Вызов метода завершается нормально, если этот вызов не вызывает исключение, либо непосредственно из JVM, либо в результате выполнения явного оператора throw.
|
||||
Если вызов текущего метода завершается нормально, то значение может быть возвращено вызывающему методу.
|
||||
Это происходит, когда вызванный метод выполняет одну из инструкций возврата, выбор которых должен соответствовать типу возвращаемого значения (если оно есть).
|
||||
|
||||
Текущий frame используется в этом случае для восстановления состояния инициатора, включая его локальные переменные и стек операндов,
|
||||
с соответствующим образом увеличенным программным счетчиком инициатора (2.1), чтобы пропустить инструкцию вызова метода.
|
||||
Затем выполнение обычно продолжается в frame вызывающего метода с возвращенным значением (если оно есть), помещаемым в стек операндов этого frame.
|
||||
|
||||
3.6. Резкое завершение вызова метода
|
||||
|
||||
Вызов метода завершается преждевременно, если при выполнении инструкции JVM в методе выдает исключение, и это исключение не обрабатывается в методе.
|
||||
Выполнение команды **athrow** также приводит к явному выбрасыванию исключения, и если исключение не перехватывается текущим методом,
|
||||
приводит к неожиданному завершению вызова метода. Вызов метода, который завершается внезапно, никогда не возвращает значение своему вызывающему.
|
Loading…
Reference in New Issue