Для разработчиков, если они не понимают JVM Java, действительно сложно написать хороший код и найти хорошие ошибки. В то же время JVM также является самой сложной областью в процессе собеседования. С сегодняшнего дня запускается серия «Подробное объяснение JVM», которая поможет вам глубже понять знания, связанные с JVM.
Мы не можем пройти собеседование ради собеседования, но если вы освоите эти базовые знания, вы обязательно станете «самой яркой звездой» на собеседовании и работе. Эта серия была впервые опубликована в публичном аккаунте WeChat «Program New Vision». Далее открываем нашу первую статью «Подробное объяснение структуры памяти JVM».
В обучении также необходимо уделять внимание методам и методам. В этой серии обучения мы проведем вас через "Метод обучения Фейнмана" учиться и пытаться использовать картинки и тексты для объяснения. Как говорится, картинка стоит тысячи слов.
подумай немного
Чтобы получить знание, нужно знать, зачем его изучать. Некоторые люди скажут, что эти написания кодов кажутся бесполезными, и кажется, что JVM делает все за нас. Затем подумайте, почему вы хотите изучить структуру виртуальной машины JVM.
Итак, вы столкнулись с такой путаницей: сколько памяти в куче должно быть установлено? Что именно вызвало исключение OutOfMemoryError? Как сделать настройку JVM? Как происходит сборка мусора JVM? Что делает JVM даже для создания объекта String?
На эти вопросы постепенно будут даны ответы при углубленном изучении, и первым шагом к решению этих проблем является понимание состава JVM.
Структура памяти JVM
Виртуальная машина Java делит память на разные области данных во время выполнения программы, как показано на рисунке ниже.
Если вы понимаете приведенный выше рисунок, структура памяти JVM, по сути, составляет его половину. Что мы видим на картинке выше? Мирянин смотрит на веселье, мирянин смотрит на дверной проем. Из рисунка можно получить следующую информацию.
Во-первых, JVM разделена на пять областей: стек виртуальной машины, собственный стек методов, область методов, куча и счетчик программ. PS: Не отказывайтесь от английского, здесь легче понять по-английски.
Во-вторых, стек виртуальной машины, локальный стек методов и счетчик программ в пяти областях JVM являются частными для потоков, а область методов и куча являются общими областями для потоков. Картинка выделена по цвету, зеленый означает "прохождение", оранжевый означает остановку на одну остановку (нужно подождать).
В-третьих, объем занимаемой памяти разных регионов JVM разный, как правило, куча самая большая, а счетчик программ маленький. Так что же будет размещено на самой большой площади? Конечно, это самый "объект" в Java.
Расширение обучения: если вы запомните эту картинку, можете ли вы сказать что-нибудь о структуре памяти JVM? Вы можете попробовать, но не заучивайте наизусть, используйте свое воображение.
куча
Выше был сделан вывод о том, что память кучи является самой большой, куча совместно используется потоками, а назначение кучи — хранить объекты. Здесь размещаются почти все экземпляры объектов. Конечно, по мере обновления методов оптимизации некоторые данные также будут помещаться в стек и т. д.
Пистолет попадает в птицу, а дерево притягивает ветер. Поскольку куча занимает самый большой объем памяти, куча также является основной областью (ключевым объектом) сборки мусора Java, поэтому ее также называют «кучей GC» (Garbage Collected Heap).
Что касается работы GC, то мы подробно поговорим о ней в следующих главах, но из-за существования GC современные сборщики в основном используют алгоритм поколенческой сборки, и куча очищается заново.
Опять же, краткий анализ содержания представлен для графика выше.
Во-первых, операция GC с кучей использует алгоритм сбора по поколениям.
Во-вторых, куча различает новое поколение и старое поколение;
В-третьих, новое поколение разделено на: пространство Эдема, пространство От выжившего (S0), пространство до выжившего (S1).
Спецификация виртуальной машины Java предусматривает, что куча Java может находиться в физически прерывистом пространстве памяти, если она логически непрерывна. То есть память кучи собирается по кусочкам. Когда вы хотите увеличить пространство в куче, вы можете «залатать» его (масштабируемость), но когда в куче нет памяти для завершения выделения экземпляра, и куча больше не может быть расширена, будет выброшено исключение OutOfMemoryError .
Область метода
Область методов и куча имеют много общего: совместное использование потоков, разрыв памяти, масштабируемость, сборка мусора и исключение OutOfMemoryError, когда оно больше не может быть расширено.
Из-за этого сходства спецификация виртуальной машины Java описывает область методов как логическую часть кучи, но в настоящее время фактически отделена от кучи Java (не куча).
Персонализация области метода заключается в том, что в ней хранятся такие данные, как информация о классе, константы, статические переменные и код, скомпилированный компилятором JIT, который был загружен виртуальной машиной.
Целью восстановления памяти в области метода является в основном восстановление пула констант и выгрузка типа.Вообще говоря, «оценка» восстановления этой области относительно неудовлетворительна, особенно выгрузка типа, условия довольно жестковато, но восстановление действительно возможно.нужно.
Регистр счетчика программ
Мы уже узнали о счетчике программ: он занимает меньше памяти и готов к личному использованию. Это единственная область, в которой нет исключения OutOfMemoryError.
Функцию счетчика программ можно рассматривать как индикатор номера строки байт-кода, исполняемого текущим потоком.Когда интерпретатор байт-кода работает, он выбирает следующую инструкцию байт-кода, изменяя значение счетчика. Среди них базовые функции, такие как ветвление, циклы, переходы, обработка исключений и восстановление потока, должны полагаться на счетчики для завершения.
Многопоточность виртуальной машины Java достигается за счет поочередного переключения потоков и распределения времени выполнения процессора.В каждый данный момент процессор (для многоядерного процессора — ядро) будет выполнять только одну нить инструкции.
Следовательно, чтобы восстановить правильную позицию выполнения после переключения потока, каждый поток должен иметь независимый программный счетчик. Счетчики между каждым потоком не влияют друг на друга и хранятся независимо. Мы называем этот тип области памяти «приватным потоком». .» из памяти.
Если поток выполняет метод Java, этот счетчик записывает адрес выполняемой инструкции байт-кода виртуальной машины; если поток выполняет метод Natvie, значение счетчика пусто (не определено).
Стеки JVM
Поток стека виртуальной машины является частным, и его жизненный цикл такой же, как и у потока.
Фрейм стека — это структура данных, используемая для поддержки вызовов и выполнения методов виртуальной машиной. Фрейм стека хранит таблицу локальных переменных метода, стек операндов, динамическое соединение и адрес возврата метода, а также другую информацию. Процесс каждого метода от вызова до завершения выполнения соответствует процессу перемещения кадра стека в стек в стеке виртуальной машины.
Таблица локальных переменных представляет собой набор областей хранения значений переменных, используемых для хранения параметров метода и локальных переменных, определенных в методе. Включая 8 основных типов данных, ссылку на объект (ссылочный тип) и тип returnAddress (указывающий на адрес инструкции байт-кода).
64-битные типы данных long и double занимают 2 пространства локальных переменных (слотов), а остальные типы данных занимают только 1.
Если глубина стека, запрошенная потоком, превышает глубину, разрешенную виртуальной машиной, будет выдано исключение StackOverflowError; если стек виртуальной машины не может запросить достаточно памяти во время динамического расширения, будет выдано исключение OutOfMemoryError.
Стек операндов, также известный как стек операций, представляет собой LIFO. По мере выполнения метода и выполнения инструкции байт-кода константа или переменная копируется из таблицы локальных переменных или поля экземпляра объекта и записывается в стек операндов, а затем элементы стека извлекаются в локальную переменную. таблицы по мере выполнения вычислений или вернуться к вызывающему методу, то есть операциям извлечения/вставки.
Динамическое связывание: в стеке виртуальной машины Java каждый фрейм стека содержит символическую ссылку на метод, которому принадлежит стек, в пуле констант времени выполнения. Цель хранения этой ссылки — поддерживать динамическое связывание во время вызова метода (динамическое связывание).
Возврат метода: независимо от того, завершается ли метод нормально или нет, он должен вернуться туда, где метод был вызван, прежде чем программа сможет продолжить работу.
Стеки нативных методов
Собственные стеки методов аналогичны стекам виртуальных машин и также вызывают исключения StackOverflowError и OutOfMemoryError.
Разница в том, что стек виртуальной машины служит виртуальной машине для выполнения методов Java (байт-код), а стек собственных методов обслуживает собственные методы, используемые виртуальной машиной.
резюме
После приведенного выше объяснения вы, должно быть, узнали основную ситуацию со структурой памяти JVM. Давайте сравним приведенную ниже карту мозга, обобщим ее и посмотрим, что вы можете сказать.
Для получения дополнительной информации из серии «Подробное объяснение JVM» и других серий вопросов для интервью, пожалуйста, обратите внимание на публичный аккаунт WeChat «Program New Vision», который будет постоянно обновляться.
Оригинальная ссылка: "Подробное объяснение структуры памяти JVM》