JVM - Введение в структуру фрейма стека времени выполнения

Java задняя часть JVM

Фрейм стека (Stack Frame) — это структура данных, используемая для поддержки виртуальной машины при вызове и выполнении метода, и это элемент стека стека виртуальной машины (Virtual Machine Stack) области данных среды выполнения виртуальной машины. Фрейм стека хранит таблицу локальных переменных метода, стек операндов, динамическое соединение и адрес возврата метода, а также другую информацию. Первый метод соответствует процессу помещения кадра стека в стек в стеке виртуальной машины от начала вызова до завершения выполнения.

Каждый кадр стека содержит局部变量表,操作数栈,动态连接,方法返回地址и一些额外的附加信息. При компиляции кода уже определяется размер таблицы локальных переменных и глубина стека операндов во фрейме стека.полностью уверени записывается в свойство Code таблицы методов,Поэтому на то, сколько памяти нужно выделить для кадра стека, не будут влиять переменные данные во время выполнения программы, а зависит только от реализации конкретной виртуальной машины..

Цепочка вызовов методов в потоке может быть очень длинной, при этом многие методы обрабатывают состояние выполнения одновременно. Для механизма выполнения в активном потоке действителен только кадр стека в верхней части стека виртуальной машины, который называется текущим кадром стека (Current Stack Frame), а метод, связанный с этим кадром стека, называется текущим. метод (текущий метод). Все инструкции байт-кода, запускаемые ссылкой выполнения, работают только с текущим кадром стека. Концептуальная структура кадра стека показана на следующем рисунке:

1. Таблица локальных переменных

Таблица локальных переменных представляет собой набор областей хранения значений переменных, используемых для хранения параметров метода и локальных переменных, определенных внутри метода. При компиляции файла класса максимальная емкость таблицы локальных переменных, которую должен выделить метод, определяется в элементе данных max_locals атрибута Code метода.

变量槽 (Variable Slot)Это наименьшая единица таблицы локальных переменных, и нет обязательного размера 32 бита, хотя 32 бита достаточно для хранения большинства типов данных. ОдинSlotможно хранитьboolean,byte,char,short,int,float,referenceиreturnAddress8 видов. вreferenceПредставляет ссылку на экземпляр объекта, с помощью которого можно получить индекс начального адреса объекта, хранящегося в куче Java, и информацию о типе данных, к которому относятся данные в области метода.returnAddressуказывает на адрес инструкции байт-кода.Для 64-битных переменных long и double виртуальная машина выделяет для них два последовательных слота..

Виртуальная машина использует таблицу локальных переменных путем индексирования. Мы уже знаем, что в таблице **local переменных хранятся параметры метода и локальные переменные. Когда вызывающий метод является нестатическим методом, слот с 0-м индексом в таблице локальных переменных используется для передачи ссылки на экземпляр объекта, которому метод принадлежит по умолчанию, то есть на объект, на который указывает " это ключевое слово. **После назначения параметров метода последовательно назначаются локальные переменные, определенные внутри метода.

Проверка повторного использования слота

Для экономии места в кадре стека можно повторно использовать слоты в таблице локальных переменных. когдавыходит за рамки некоторых переменныхПосле этого слоты, соответствующие этим переменным, можно передать другим переменным для использования. Этот механизм иногда влияет на поведение сборки мусора.

public class Main {
    public static void main(String[] args) {
        byte[] placeholder = new byte[64*1024*1024];
        System.gc();
    }
}
[GC (System.gc())  69468K->66384K(188416K), 0.0016481 secs]
[Full GC (System.gc())  66384K->66280K(188416K), 0.0079337 secs]
public class Main {
    public static void main(String[] args) {
        {
            byte[] placeholder = new byte[64*1024*1024];
        }
        int a = 0;
        System.gc();
    }
}
[GC (System.gc())  69468K->66368K(188416K), 0.0012876 secs]
[Full GC (System.gc())  66368K->744K(188416K), 0.0055897 secs]

Видно, что когда я помещаю объявление byte только в блок кода, а затем выполняю код вне области действия, gc освобождает слот.

Уведомление: JVM не присваивает начальные значения локальным переменным, только глобальным переменным.

2. Стек операндов

Стек операндов, также известный как стек операций, представляет собой стек по принципу «последний вошел — первый вышел». max_stacks в атрибуте Code файла Class указывает максимальную глубину стека во время выполнения. Механизм выполнения интерпретации виртуальной машины Java называется «механизм выполнения на основе стека», где стек относится к стеку операндов.

Арифметические операции при выполнении метода или при вызове других методов для передачи параметров выполняются через стек операндов.

JVM оптимизация стека операндов

В концептуальной модели два кадра стека независимы друг от друга. Но большинство реализаций виртуальных машин оптимизированы таким образом, что два кадра стека выглядят как один.частичное перекрытие. Пусть нижняя часть стека операндов перекрывается с верхней таблицей локальных переменных, чтобы часть данных могла совместно использоваться при вызове метода,Нет необходимости в дополнительной передаче копии параметра.

3. Динамические ссылки

Каждый кадр стека содержит ссылку на метод, которому принадлежит кадр стека в пуле констант времени выполнения.Эта ссылка сохраняется для поддержки динамической компоновки во время вызова метода.

В файле класса хранится большое количество символических ссылок, и инструкция вызова метода в байт-коде принимает в качестве параметра символическую ссылку, указывающую на метод в пуле констант. Некоторые из этих символических ссылок будут在类加载阶段或第一次使用时转化为直接引用, это преобразование называетсястатический анализ. Другая часть будет каждый раз运行期间转化为直接引用, эта часть называетсядинамическая ссылка.

4. Адрес возврата метода

Когда метод начинает выполняться, есть только два способа выйти из текущего метода.:

  1. Когда выполнение сталкивается с инструкцией возврата, возвращаемое значение будет передано вышестоящему вызывающему методу.Этот метод выхода называется завершением нормального вызова метода (нормальное завершение вызова метода).Вообще говоря,调用者的PC计数器可以作为返回地址.
  2. Когда выполнение сталкивается с исключением и текущее тело метода не обрабатывается, это приведет к выходу из метода.В это время нет возвращаемого значения, которое называется завершением вызова метода.返回地址要通过异常处理器表来确定.

Когда метод возвращается, возможны 3 операции:

  1. 恢复Таблица локальных переменных и стек операндов верхнего метода
  2. поместите возвращаемое значение压入Стек операндов кадра стека вызывающего абонента
  3. 调整Значение счетчика ПК, указывающее на инструкцию, следующую за инструкцией вызова метода.

5. Дополнительная информация

Спецификация виртуальной машины позволяет конкретной реализации виртуальной машины добавлять некоторую информацию, не описанную в спецификации, во фрейм стека, например информацию, связанную с отладкой, которая полностью зависит от конкретной реализации виртуальной машины. В реальной разработке динамическое соединение, адрес возврата метода и другая дополнительная информация обычно классифицируются в одну категорию, которая называется информацией кадра стека.