1 макет области памяти JVM
- Выполнение java-кода состоит из трех шагов.
- исходный файл java -> компилятор -> файл байт-кода
- Файл байт-кода->JVM->машинный код
- Машинный код -> выполнение системного процессора
- Байт-код, выполняемый JVM, должен быть загружен путем загрузки класса; файл байт-кода может быть получен из локального файла, может быть получен в сети или может быть сгенерирован в режиме реального времени. То есть вы можете пропустить этап написания java-кода и напрямую генерировать байт-код для выполнения JVM.
- Среди них стек виртуальной машины Java, счетчик программ, куча, локальный стек методов и метапространство относятся к памяти среды выполнения JVM;обмен потокамиможно разделить на две категории
- Куча JAVA и MetasSpace совместно используются потоками; стек виртуальной машины, собственный стек методов и счетчик программ являются частными для потоков.
2 Введение в пять основных областей данных JVM
-
2.1 Счетчик программ (регистр счетчика программ)
- Небольшой объем памяти, который является индикатором номера строки байт-кода, выполняемого текущим потоком. Поток имеет уникальный программный счетчик, который требуется для разбора байт-кода для выбора следующей инструкции, и на него полагаются переходы, циклы, переходы и т. д.
- Счетчик потока, выполняющего метод java, записывает адрес инструкции байт-кода виртуальной машины; если это все еще метод Native, он пуст.
- Область памяти счетчика программ — единственная область в виртуальной машине, в которой не указаны ошибки OutOfMemoryError.
-
2.2 Стек виртуальных машин
- Модель памяти для выполнения метода Java: каждый метод создает кадр стека (Stack Frame) для хранения такой информации, как таблица локальных переменных, стек операндов, динамическая ссылка, выход из метода и т. д.
- Процесс каждого метода от вызова до завершения выполнения соответствует процессу отправки кадра стека до его извлечения из стека в стеке виртуальной машины.
- Фрейм стека — это структура данных, используемая для хранения данных и частичных результатов процесса, а также для обработки динамической компоновки, возвращаемых значений метода и исключения отправки. Кадры стека создаются с помощью вызовов метода и уничтожаются с завершением метода (независимо от того, завершается ли метод нормально или ненормально).
- Если глубина стека, запрошенная потоком, больше, чем глубина, разрешенная виртуальной машиной, будет выброшена ошибка StackOverflowError; когда расширение не может быть применено для достаточного количества памяти, будет выброшена ошибка OutOfMemeryError.
-
2.3 Стек собственных методов
- Стек локальных методов аналогичен стеку виртуальной машины, разница в том, что стек виртуальной машины обслуживает выполнение методов Java, а локальный стек методов обслуживает собственный метод. (Реализация HopShot напрямую объединяет локальный стек методов и стек виртуальной машины в один)
- Вышеупомянутые три типа областей имеют тот же жизненный цикл, что и Thread, то есть: при создании потока создается соответствующая область памяти, а при уничтожении потока освобождается соответствующая память.
-
2.4 Куча
- Область памяти, совместно используемая потоками, почти все экземпляры объектов выделяют здесь память, и это также самая важная область памяти для сборки мусора сборщиком мусора. Поэтому его часто называют кучей GC.
- Частный буфер распределения потока (Thread Local Allocation Buffer) также делится в куче.
- Версия JDK8, поскольку метапространство используется вместо постоянной генерации, пул строковых констант и статические переменные класса также помещаются в кучу java
-
2.5 Метапространство
- В основном он хранит метаданные класса, такие как различная информация описания класса, имя класса, метод, поле, ограничения доступа и т. д., то есть такие данные, как код, скомпилированный компилятором
- постоянный пул времени выполнения: В дополнение к версии класса, полям, методам и другим описаниям в Class файле также есть постоянный пул, который используется для хранения различных литералов и символьных ссылок, сгенерированных во время компиляции, которые будут сохранены после загрузки класса. в постоянный пул времени выполнения метапространства
-
Причины использования метапространства вместо постоянной генерации
- Размер постоянной генерации фиксируется при запуске, и его сложно настроить; если он слишком велик, легко вызвать переполнение постоянной генерации; если он слишком мал, легко сгенерировать OutOfMemeryError во время выполнения.
- Строка существует в постоянной генерации, с которой возникают проблемы при использовании, так как памяти постоянной генерации часто не хватает, выскакивает исключение OutOfMemoryError: PermGen.
-
CodeCache
- Пространство памяти, в котором хранится собственный код, сгенерированный JVM, называется Кэш кода; JIT-компиляция, JNI и т. д. компилируют код в собственный код, а собственный код, сгенерированный JIT, занимает большую часть пространства в коде. Кэш
- прямая память
- Он не является общей частью области данных среды выполнения виртуальной машины и не определен в спецификации. JDK1.4 представил режим ввода-вывода Channel (канал) и Buffer (буферная область), который может использовать собственную функцию для выделения памяти вне кучи и работать через DirectByteBuffer.
3 Различия между компоновкой памяти среды выполнения JVM и моделью памяти JMM
- Область памяти JVM относится к разделению данных памяти во время работы JVM, подчеркивая разделение пространства памяти.
- Модель памяти JAVA — это спецификация языка Java для операций с общей памятью переменных в случае многопоточного параллелизма: решение проблем видимости и атомарности переменных в многопоточности
4 Взаимодействие модели памяти JMM
-
Существует восемь типов операций взаимодействия с памятью, а реализация виртуальной машины гарантирует, что каждая операция является атомарной.
- lock (замок): переменная, действующая на основную память, идентифицирующая переменную как состояние монопольного потока
- разблокировать (разблокировать): переменная, которая воздействует на основную память, освобождает переменную, находящуюся в заблокированном состоянии, а освобожденная переменная может быть заблокирована другими потоками
- чтение (чтение): действует на переменную основной памяти и считывает переменные, используемые в последующей операции загрузки, из основной памяти.
- load (загрузить): воздействовать на переменные в основной памяти и помещать только что прочитанное значение в копию рабочей памяти.
- use (использование): Воздействует на переменные в рабочей памяти.Когда поток выполняет инструкцию байт-кода и ему необходимо использовать соответствующую переменную, копия переменной в рабочей памяти передается механизму выполнения.
- assign (назначение): действие над переменными в рабочей памяти, помещение значения, полученного от исполнительного механизма, в переменную копию рабочей памяти
- store (хранение): воздействует на переменные в рабочей памяти и отправляет переменные в рабочей памяти в основную память для последующего использования при записи
- write (запись): воздействовать на переменные в основной памяти и записывать значения переменных в рабочей памяти хранилища в основную память
- чтение и загрузка кажутся одной и той же операцией? Каковы ваши мысли, пожалуйста, посоветуйте
-
JMM сформулировал следующие правила использования этих восьми инструкций.
- чтение и загрузка, сохранение и запись должны выполняться последовательно, и должны появиться две инструкции, то есть должна быть загрузка, когда происходит чтение
- Поток не может отменить самую последнюю операцию присваивания.После изменения переменной в рабочей памяти она должна быть синхронизирована с основной памятью путем записи
- Потоку не разрешено синхронизировать переменные, которые не были назначены основной памяти.
- Новые переменные должны рождаться в основной памяти, а в рабочей памяти не разрешается использовать неинициализированные переменные; перед использованием и сохранением управляющих переменных они должны пройти через операции загрузки и назначения
- Только один поток может блокировать переменную одновременно. Поток может блокировать переменную несколько раз. Чтобы снять блокировку, ему необходимо выполнить одинаковое количество операций разблокировки. Блокировка и разблокировка должны встречаться парами.
- Переменная не имеет блокировки и не может быть разблокирована, а поток не может разблокировать переменную, заблокированную другими потоками.
- Перед выполнением разблокировки переменные в рабочей памяти должны быть синхронизированы с основной памятью
- Для выполнения операции блокировки нужно очистить рабочую память (всю), а перед тем, как использовать переменную, нужно заново выполнить операции загрузки и присваивания
Добро пожаловать на ошибку в тексте
Обратите внимание на публичный номер и общайтесь вместе
Справочная статья
- Глубокое понимание виртуальной машины Java
- Структура памяти JVM очень детализирована.[1]
- Один из метапространств: общее введение в метапространство[2]
использованная литература
[1]Структура памяти JVM очень детализирована:https://blog.csdn.net/mayfly_hml/article/details/102805030
[2]Один из Metaspace: Общее введение Metaspace:https://www.cnblogs.com/duanxz/p/3520829.html