Глубокое понимание структуры памяти JVM JVM

JVM

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

Структура памяти JVM

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

Счетчик программы — это индикатор номера строки байт-кода, выполняемого текущим потоком.Он укажет адрес следующей инструкции для выполнения.Интерпретатор байт-кода выбирает следующую операцию, выполняемую программой, изменяя значение счетчика.

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

  • Если поток выполняетсяJavaметод, счетчик записывает адрес исполняемой инструкции байт-кода виртуальной машины
  • Если вы выполнитеnativeметод, счетчик пуст

Это также единственный, который не появляетсяOutOfMemoryErrorобласть памяти.

Стек виртуальной машины Java

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

Как правило, так называемый «стек» относится к части таблицы локальных переменных стека виртуальной машины, в которой хранятся различные основные типы данных (8виды), ссылки на объекты (referenceтипа) иreturnAddressтип. Пространство, необходимое для таблицы локальных переменных, определяется и выделяется во время компиляции и не изменяется во время выполнения метода.

JavaВ виртуальном стеке могут возникать два типа исключений:

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

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

собственный стек методов сJavaРоль стека виртуальной машины аналогична, разницаJavaСтек виртуальной машины выполняется для виртуальной машиныJavaслужбы методов, в то время как собственный стек методов выполняется для виртуальной машины.Nativeсервис метода. Некоторые виртуальные машины (например,HotSpotвиртуальная машина) напрямую поместите собственный стек методов иJavaСтеки виртуальных машин объединяются.

Стек нативных методов также может генерироватьStackOverflowErrorиOutOfMemoryErrorаномальный.

куча Java

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

JavaКуча также называется"GC"куча. С точки зрения утилизации памяти ее можно разделить на новое поколение и старое поколение. Новое поколение можно разделить наEdenПлощадь,From SurvivorПлощадь,To SurvivorРайон и др.

JavaРеализация кучи может быть фиксированной или расширенной. Текущие виртуальные машины реализованы в соответствии с масштабируемостью, через-Xmxи-XmsКонтролируйте размер кучи.

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

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

область метода сJavaКак и куча, она разделяется потоками. Он используется для хранения таких данных, как информация о классе, константы, статические переменные и код, скомпилированный компилятором JIT, который был загружен виртуальной машиной. также называемыйNon-Heap(не куча).

Если область метода не может удовлетворить требования к выделению памяти, она выдастOutOfMemoryErrorаномальный.

постоянный пул времени выполнения

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

Dynamics — это постоянный пул времени выполнения относительноClassВажной особенностью пула файловых констант является то, что константы не обязательно генерировать только во время компиляции, а новые константы также могут быть помещены в пул во время выполнения.

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

прямая память

Прямая память неJVMуправление, это использованиеNativeбиблиотека функций вJavaОбласть памяти, выделенную приложением за пределами кучи, можно избежать вJavaкуча иNativeДанные копируются в кучу для повышения производительности.

НапримерNIOсерединаDirectByteBufferВы можете оперировать прямой памятью как ссылкой на эту память.

Постоянное поколение и метапространство

Иногда вы увидите область метода, называемую постоянной генерацией, но между ними есть существенная разница. Область методаJVMопределяется в спецификации, а постоянная генерацияJVMреализация спецификации, и только еслиHotSpotЭто верно для виртуальных машин, и в других виртуальных машинах нет постоянной генерации.

существуетJDK1.6До,HotSpotвиртуальная машинаGCКоллекция поколений распространяется на область метода, или область метода реализуется с использованием постоянной генерации. Но навсегда-XX:MaxPermSizeверхний предел, легко столкнуться с проблемами переполнения памяти.

так вJDK1.7, некоторые данные были переданыJava HeapилиNative HeapНапример: переместите статические переменные пула строк и класса, изначально помещенные в постоянное поколение, вJava Heap, перенесите символическую ссылку наNative Heapсередина. Но постоянное поколение все еще существует и не удаляется.

существуетJDK1.8, постоянное поколение устраняется и заменяется реализацией метапространства, которая такжеJVMРеализация области метода в спецификации. Однако самая большая разница между ним и постоянным поколением заключается в том, что метапространство находится не в виртуальной машине, а в локальной памяти. Таким образом, по умолчанию он ограничен только локальной памятью, доступ к которой можно получить через-XX:MetaspaceSizeПараметр задает начальный размер пространства, и по умолчанию максимальное пространство не ограничено.

Распространенные OOM и их причины

JavaсерединаOOMозначаетjava.lang.OutOfMemoryErrorаномальный. В основном это следующие:

java.lang.OutOfMemoryError:Java heap space

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

Основные причины переполнения памяти:

  • Объем доступа к трафику велик, превышает установленный размер кучи;
  • Утечки памяти, объекты, которые нельзя переработать, занимают слишком много места в куче;

java.lang.OutOfMemoryError:Permgen space

существуетJDK7середина,HotSpotВиртуальная машина использует постоянную генерацию для реализации области метода.Постоянная генерация мала, а эффективность повторного использования низкая, что склонно к переполнению памяти.

следовательно,JDK8Постоянная генерация отменяется, и метапространство используется для реализации области метода, которая хранится в локальной памяти.

java.lang.OutOfMemoryError:Metaspace

Область метода в основном хранит метаинформацию класса,HotSpotОбласть метаданных. Это исключение возникает, когда в метапространстве недостаточно места, выделенного для загруженного класса.

Основными причинами нехватки места в области метаданных являются:

  • Загружено слишком много классов, распространено вjspКогда страниц слишком много;
  • Мета-пространство реализовано вне кучи и в основном ограничено памятью самого процесса, и его вообще сложно переполнить.

использованная литература