В процессе выполнения Java-программы виртуальная машина Java делит память, которой она управляет, на несколько разных областей данных, в том числе в целом следующие области данных времени выполнения.
1. Регистр счетчика программ
Счетчик программ — это небольшое пространство памяти, которое выполняет:
1.1 Можно рассматривать как индикатор сигнала байт-кода, выполняемого текущим потоком. Интерпретатор байт-кода выбирает следующую инструкцию байт-кода для выполнения, изменяя значение счетчика.Основные функции, такие как ветвление, цикл, переход, обработка исключений и восстановление потока, зависят от завершения счетчика.Примечание. Однако, если текущий поток выполняет собственный метод, счетчик программ пуст.
1.2 В случае многопоточности счетчик программ используется для записи позиции выполнения текущего потока, так что, когда поток переключается обратно, он может знать, где поток был запущен в последний раз.
Особенности: Поток частный, жизненный цикл создается с созданием потока и умирает с окончанием потока. Эта область памяти является единственной областью, в которой не указаны какие-либо условия OutOfMemoryError в спецификации виртуальной машины Java.
2. Стек виртуальной машины Java
Ява Как и счетчик программ, стек виртуальной машины также является частным для потока, и его жизненный цикл такой же, как и у потока. Стек виртуальной машины описывает Java Модель памяти выполнения метода: при выполнении каждого метода одновременно создается кадр стека (Stack Frame) используется для хранения такой информации, как таблица локальных переменных, стек операндов, динамическая ссылка, выход из метода и т. д. каждый метод называется Процесс до завершения выполнения соответствует процессу помещения кадра стека в стек в стеке виртуальной машины.
В таблице локальных переменных хранятся различные основные типы данных (логические, байтовые, символьные, короткие, целые, float, long, double), ссылки на объекты (ссылочный тип) и тип returnAddress (указывает на слово адрес инструкции кода раздела). Среди них long и double 64-битной длины будут занимать 2 пространства локальных переменных (Slot, 32-бит), а другие типы данных занимают только 1 Кусок. Пространство, необходимое для таблицы локальных переменных, выделяется во время компиляции.При входе в метод определяется, сколько места для локальной переменной необходимо выделить во фрейме, и локальные переменные не будут изменены во время выполнения метода. размер шкалы. Таблица локальных переменных создается при выполнении метода вместе с созданием кадра стека. Более того, размер таблицы локальных переменных определяется во время компиляции, и ей нужно выделить заранее определенный размер только при ее создании. Кроме того, размер таблицы локальных переменных не меняется во время работы метода.
Спецификация виртуальной машины Java определяет два исключения из этой области:
2.1 Если глубина запроса потока больше, чем глубина, разрешенная виртуальной машиной, происходит переполнение стека, например, рекурсия, броски
Исключение StackOverflowError.
2.2 Когда динамическое расширение стека виртуальной машины не может быть применено для достаточного объема памяти, генерируется исключение OutOfMemoryError.
Когда метод передает параметры, на самом деле это метод, который передает копию таблицы локальных переменных в своем собственном фрейме стека в таблицу локальных переменных в фрейме стека другого метода (обратите внимание на копию, а не на себя), независимо от типа данных ( базовый тип, ссылочный тип)
3. Стек собственных методов
Виртуальная машина Java может использовать традиционный стек для поддержки выполнения нативных методов (методов, написанных на языках, отличных от Java). Частный поток, такой как виртуальная машина Sun HotSpot, напрямую объединяет собственный стек методов и стек виртуальной машины в один. Спецификация виртуальной машины Java определяет два исключения из этой области:
3.1. Если глубина, запрошенная потоком, больше, чем глубина, разрешенная виртуальной машиной, генерируется исключение StackOverflowError.
3.2 Когда динамическое расширение стека виртуальной машины не может быть применено для достаточного объема памяти, генерируется исключение OutOfMemoryError.
4. Куча Java
Ява Куча — это Java Самая большая часть памяти управления виртуальной машиной — это область памяти, совместно используемая всеми потоками, созданная при запуске виртуальной машины. Единственная цель этой области — хранить экземпляры объектов, и почти все экземпляры объектов размещаются в куче. Спецификация виртуальной машины Java утверждает, что Java Куча может находиться в физически прерывистом пространстве памяти, если она логически непрерывна. Как и дисковое пространство, она может быть реализована как фиксированный размер или расширенный. Текущие основные виртуальные машины Реализовано как расширение (управляется через -Xmx и -Xms).
Куча Java является основной областью, управляемой сборщиком мусора, поэтому ее также называют «кучей GC».Его можно разделить на новое поколение и старое поколение в подразделе; новое поколение можно разделить на пространство Эдема, от Пространство выжившего и пространство ToSurvivor.
Ява В спецификации виртуальной машины указано исключение OutOfMemoryError для этой области: если в куче нет памяти для завершения выделения экземпляра, и куча больше не может быть расширена, она выбрасывается Исключение OutOfMemoryError. (Когда старая область заполнена, выполните полную сборку мусора. После полной сборки, если выживший и Старая область по-прежнему не может хранить некоторые объекты, скопированные из Eden, тогда возникает ошибка OOM/или напрямую сохраняются большие объекты и большие массивы, что приводит к нехватке места в старом возрасте)
5. Область метода
Как и куча Java, область методов — это область памяти, совместно используемая всеми потоками и используемая для хранения таких данных, как информация о классе, константы, статические переменные и код, скомпилированный компилятором реального времени, который был загружен виртуальной машиной. В HotSpot постоянное поколение используется для реализации области метода, в то время как другие виртуальные машины (такие как BEA JRockit, IBM J9 и т. д.) не имеют постоянного поколения.
В Java7 пул констант времени выполнения был удален из постоянного поколения, а в куче Java (Heap) открыта область для хранения пула констант времени выполнения. В Java8 вообще нет постоянной генерации, а область методов размещается непосредственно в области локальной памяти, не связанной с кучей, которая называется метапространством.
Суть метапространства аналогична сущности перманентного поколения. Реализация области метода в спецификации JVM. Но самая большая разница между метапространством и постоянным поколением заключается в том, что метапространство находится не в виртуальной машине, а использует локальную память. Поэтому по умолчанию мета Размер пространства ограничен только локальной памятью, но размер метапространства может быть указан следующими параметрами: -XX:MetaspaceSize, начальный размер пространства. -XX:MaxMetaspaceSize, максимальное пространство, по умолчанию нет ограниченное. Спецификация виртуальной машины Java определяет исключение OutOfMemoryError для области метода: если пространство памяти области метода не может удовлетворить запрос на выделение памяти, тогда Виртуальная машина Java вызовет исключение OutOfMemoryError.
6. Пул констант времени выполнения
Пул констант времени выполнения является частью области методов. обмен потоками. В дополнение к версии класса, полям, методам, интерфейсам и другой информации в файле класса также есть пул констант, который используется для хранения различных литеральных констант и символических ссылок, сгенерированных во время компиляции.Эта часть содержимого хранится в класс после загрузки в постоянный пул области методов.
Статические измененные статические переменные также хранятся в области методов, но не в пуле констант (локальные переменные не могут быть изменены), статические переменные не могут быть определены внутри метода (может быть final) и могут быть определены только как переменные-члены.
Когда класс загружается виртуальной машиной Java, константы в файле класса сохраняются в пуле констант среды выполнения области методов. А во время выполнения в пул констант можно добавлять новые константы. Например, метод intern() класса String может добавлять строковые константы в пул констант во время выполнения.
Когда на некоторые константы в пуле констант времени выполнения не ссылаются объекты и не ссылаются переменные, они должны быть собраны сборщиком мусора.
Спецификация виртуальной машины Java определяет исключение OutOfMemoryError для этой области: когда константный пул не может примениться к памяти, генерируется исключение OutOfMemoryError.
7.прямая память
Прямая память — это память, отличная от виртуальной машины Java, но также может использоваться Java.
В NIO представлен метод ввода-вывода на основе каналов и буферов. Он может напрямую выделять память вне виртуальной машины Java, вызывая нативный метод, а затем напрямую оперировать памятью через объект DirectByteBuffer, хранящийся в куче Java, без предварительного копирования данных из внешней памяти в кучу и последующего выполнения операций, тем самым улучшая оперативность манипулирования данными.
Размер прямой памяти не контролируется виртуальной машиной Java, но поскольку это память, при нехватке памяти будет выдано исключение OOM.
8,кадр стека
Фрейм стека — это структура данных, используемая для поддержки вызовов и выполнения методов виртуальной машиной, это область данных времени выполнения виртуальной машины. Элемент стека стека виртуальной машины. Фрейм стека хранит таблицу локальных переменных метода, стек операндов, динамическую ссылку и адрес возврата метода. и другая информация. Первый метод, от начала вызова до завершения выполнения, соответствует кадру стека в стеке виртуальной машины от стека к стеку. процесс. При компиляции кода размер таблицы локальных переменных и глубина стека операндов в кадре стека полностью определяются и записываются в Код таблицы методов. атрибут, поэтому процесс не будет влиять на то, сколько памяти необходимо выделить кадру стека. Влияние переменных данных во время выполнения программы зависит только от реализации конкретной виртуальной машины. Цепочка вызовов методов в потоке может быть очень длинной, при этом многие методы обрабатывают состояние выполнения одновременно. для исполняющего движка В активном потоке действителен только фрейм стека в верхней части стека виртуальной машины, который называется текущим фреймом стека. Frame), метод, связанный с этим кадром стека, называется текущим методом (Current Method).
8.1 Таблица локальных переменных
Локальная скалярная таблица — это место для хранения набора значений переменных, одно в слове, из Массив с отсчетом от 0 для хранения параметров метода и локальных переменных. Слот переменной (Variable Slot) — это наименьшая единица таблицы локальных переменных, и нет обязательного размера 32 бит, хотя для большинства типов данных достаточно 32 бит. Слот может хранить логическое значение, 8 типов byte, char, short, int, float, reference и returnAddress. где таблица ссылок Показывает ссылку на экземпляр объекта. returnAddress указывает на адрес инструкции байт-кода. для 64-битного длинного и двойного переменной, виртуальная машина назначает ей два последовательных слота космос. Виртуальная машина использует таблицу локальных переменных путем индексирования. Мы уже знаем, что в таблице локальных переменных хранятся параметры метода и локальные переменные. когда вызывающий метод не является статическим При вызове метода слот с 0-м индексом в таблице локальных переменных используется для передачи ссылки на экземпляр объекта, которому метод принадлежит по умолчанию, то есть на объект, на который указывает ключевое слово this. После назначения параметров метода Локальные переменные, определенные внутри метода, выделяются по очереди.
Для экономии места в кадре стека можно повторно использовать слоты в таблице локальных переменных. После выхода из области действия некоторых переменных слоты, соответствующие этим переменным, могут использоваться другими переменными.
8.2, стек операндов
Стек операндов организован как массив длин слов. Но не по индексу, а стандартными операциями со стеком — push и pop. Арифметические операции при выполнении метода или при вызове других методов для передачи параметров выполняются через стек операндов.
В концептуальной модели два кадра стека независимы друг от друга. Но большинство реализаций виртуальных машин оптимизированы таким образом, что два кадра стека частично перекрываются. Пусть нижняя часть стека операндов перекрывается с верхней таблицей локальных переменных, чтобы часть данных можно было совместно использовать при вызове метода, и не нужно было копировать и передавать дополнительные параметры.
8.3 Область данных кадра
Кадрам стека нужны некоторые данные для поддержки синтаксического анализа постоянного пула, нормальных возвратов методов, обработки исключений и т. д. Сохранить в области данных кадра
Программам удобно обращаться к пулу констант, обращаясь к указателю пула констант. Кроме того, когда функция возвращается или возникает исключение, виртуальная машина должна Кадр стека вызывающей функции должен быть восстановлен, а вызывающая функция продолжает выполняться. Для обработки исключений виртуальная машина должна иметь Таблица обработки исключений используется для поиска кода для обработки исключения при возникновении исключения, поэтому таблица обработки исключений также является важной частью области данных фрейма.
8.3.1 Динамическое связывание
Каждый фрейм стека содержит ссылку на метод в пуле констант времени выполнения, к которому принадлежит фрейм стека.
Поддерживается динамическое связывание во время вызова метода. Часть символьной ссылки будет преобразована в прямую ссылку на этапе загрузки класса или при первом использовании, и это преобразование называется статическим разрешением. Другая часть преобразуется в прямую ссылку во время каждого запуска, эта часть называется динамической компоновкой.
8.3.2 Адрес возврата метода
Когда метод начинает выполняться, есть только два способа выйти из метода. Во-первых, исполнительный механизм встречает инструкцию байт-кода, возвращенную любым методом, и в это время может быть возвращаемое значение, переданное вызывающему методу верхнего уровня.
Другой способ выхода — когда во время выполнения метода возникает исключение, которое не обрабатывается в теле метода. Независимо от того, какой метод выхода используется, после завершения метода необходимо вернуться в то место, где метод был вызван, прежде чем программа сможет продолжить выполнение.
8.4 OutOfMemoryError
Установите -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError в eclipse (минимальное и максимальное значения кучи устанавливаются одинаковыми, чтобы избежать автоматического расширения, и выводить информацию при переполнении памяти)
Куча Java используется для хранения экземпляров объектов.Поскольку объекты создаются непрерывно и существует доступный путь между корнями GC и объектами, чтобы избежать сборки мусора, возникает исключение переполнения памяти, когда количество объектов достигает максимального размера кучи.