Анализ раздела памяти JVM

Java JVM

Управление памятью - это базовый навык, которым должны овладеть разработчики, иначе программа всегда будет падать с различными неуловимыми ошибками.Некоторые языки, такие как C и C++, разработчики задействуют для памяти сами и освобождают их после использования, но неправильные привычки написания кода Это часто приводит к таким ошибкам, как утечка памяти, обращение к нулевым указателям и т. д., а Java проделала за нас большую работу с помощью виртуальных машин, чтобы разработчики могли вылезти из глубокой ямы управления памятью, но из-за На этом уровне виртуальных машин возникают проблемы. Стратегии преодоления в настоящее время более эффективны, и требуется глубокое понимание механизма управления памятью виртуальной машины.

Эта статья является лишь грубым введением в общее распределение области памяти виртуальной машины, чтобы новички могли составить себе общее впечатление, а начало впечатления основано на следующей картинке:

Область памяти Java разделена на две большие области, одна часть совместно используется потоками, а другая часть уникальна для каждого потока. Когда я впервые узнал о программировании, у меня сложилось общее впечатление, что стековая память существует в теле метода, определенные переменные являются стековой памятью, и метод закончен, а куча памяти применяется для использования ключевого слова new. Конечно, это только понимание толстой линии.Следующие блоки описывают распределение памяти на рисунке выше.

счетчик команд

Подобно регистру ПК в ЦП, он используется для хранения адреса следующей инструкции, но виртуальная машина не использует счетчик программ ЦП, а создает область в памяти для имитации счетчика команд ЦП. Измените значение счетчика, чтобы выбрать следующую инструкцию байт-кода, которую необходимо выполнить.Основные функции, такие как ветвление, цикл, переход, исключения и восстановление потока, зависят от счетчика.

Каждый поток Java имеет свой собственный счетчик, и счетчики не влияют друг на друга, поэтому при возобновлении приостановленного потока он все еще может возобновиться со счетчика и продолжить выполнение после возобновления. Таким образом, счетчик программ также изолирован от потоков. При выполнении Java-метода в счетчике сохраняется адрес байт-кода виртуальной машины, а при выполнении Native-метода он пуст (не определен). Ошибка OutOfMemoryError для этого региона не возникает.

стек виртуальных машин

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

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

Сборщик мусора Java не будет восстанавливать содержимое стека, потому что содержимое стека всегда автоматически освобождается с окончанием метода. Таблица локальных переменных содержит различные известные во время компиляциибазовый тип данных,ссылка на объектиreturnAddress. Базовый тип данных — это 8 основных типов данных Java (boolean, byte, char, short, int, float, long, double), ссылка на объект, вы можете думать об этом как об указателе на фактический адрес объекта или дескрипторе, представляющем объект , returnAddress — это адрес инструкции байт-кода. При входе в метод пространство, которое ему нужно выделить, известно во время компиляции.

Следующие два исключения могут быть зарегистрированы в стеке виртуальной машины:

  • StackOverflowError: поток запросил глубину стека больше разрешенной глубины
  • OutOfMemoryError: большинство стеков виртуальных машин могут быть динамически расширены и будут выброшены, если не будет запрошено достаточно памяти.

собственный стек методов

В отличие от стека виртуальной машины, который выполняет методы Java, локальный стек методов является собственной службой методов, используемой виртуальной машиной.Когда мы смотрим на исходный код некоторых библиотек, мы обычно находим его в конце и реализуем с помощью нативный метод, но в спецификации виртуальной машины язык, используемый нативным методом, жестко указан, поэтому виртуальная машина может реализовать его произвольно. Стек собственных методов и стек виртуальных машин в HotSpot объединены.

куча

По крайней мере, с момента изучения C мы слышали, что метод malloc выделяет место в куче. Объекты-экземпляры также размещаются в куче Java. В соответствии со спецификацией виртуальной машины в основном все экземпляры объектов и массивы размещаются в куче, например объекты, на которые указывают ссылки на объекты в стеке выше, размещаются в куче. Но с развитием технологии компиляции не так чисто, чтобы все объекты размещались в куче.

Куча также является основным местом сборки мусора (GC). Современные сборщики в основном используют алгоритм сбора поколений, поэтому куча также может быть разделена на новое поколение и старое поколение, а затем есть пространство Эдема, пространство «От выжившего» и пространство «До выжившего». Поскольку в виртуальной машине реализована автоматическая сборка мусора, в Java новые объекты в куче не нужно освобождать вручную.

мы можем пройти-Xmxи-XmsУправляет размером кучи по умолчанию. Если в куче больше нет выделенной памяти,OutOfMemoryErrorаномальный.

область метода

Область метода также является областью, разделяемой между потоками, обычно хранящей загруженныеИнформация о классе, константы, статические переменные, код, скомпилированный JIT-компиляторомданные. В общем, многие люди также называют область метода постоянным поколением. По сути, только команда HotSpot расширила генерационную коллекцию GC на область методов, чтобы сборщик мусора мог высвобождать память области методов целиком, но другие реализации виртуальных машин этого не сделали, и постоянной генерации нет. , Сам HotSpot также имеет постоянный пул в постоянном поколении, который был удален на JDK 1.7.

Условно говоря, сборка мусора не очень часто происходит в области методов. Эта область в основном перерабатывает постоянный пул и типовую разгрузку, но на самом деле условия для переработки двух крайне суровые, и сборы происходят редко.

Пул констант времени выполнения является частью области методов. Файл класса содержит информацию о пуле констант, которая используется для хранения различных литералов и символических ссылок, сгенерированных во время компиляции. Эта часть входит в пул констант времени выполнения области методов после загрузки класса. Эта часть может относиться к моему:Глубокое понимание формата файла класса JVM