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Когда страниц слишком много; - Мета-пространство реализовано вне кучи и в основном ограничено памятью самого процесса, и его вообще сложно переполнить.