Основы: структура памяти среды выполнения JVM

Java
Основы: структура памяти среды выполнения JVM

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