1: Что такое JVM
JVM — это аббревиатура от Java Virtual Machine (Виртуальная машина Java).JVM — это спецификация для вычислительных устройств.Это вымышленный компьютер, реализованный путем имитации различных компьютерных функций на реальном компьютере. Виртуальная машина Java включает в себя набор инструкций байт-кода, набор регистров, стек, кучу для сборки мусора и поле метода хранения. JVM скрывает информацию, относящуюся к конкретной платформе операционной системы, так что программе Java нужно только генерировать объектный код (байтовый код), работающий на виртуальной машине Java, и она может работать на различных платформах без изменений. Когда JVM выполняет байт-код, он фактически интерпретирует байт-код как машинные инструкции на определенной платформе для выполнения.
2: Какова связь между JRE/JDK/JVM
JRE (JavaRuntimeEnvironment, среда выполнения Java), которая является платформой Java. Все Java-программы должны выполняться под JRE. Обычным пользователям достаточно запустить разработанную java-программу и установить JRE.
JDK(Java Development Kit)Это набор инструментов разработки, используемый разработчиками программ для компиляции и отладки программ Java. Инструменты JDK также являются программами Java, для работы которых также требуется JRE. Чтобы сохранить независимость и целостность JDK, JRE также является частью установки во время установки JDK. Поэтому в каталоге установки JDK есть каталог с именем jre, который используется для хранения файлов JRE.
JVM (JavaVirtualMachine, виртуальная машина Java)является частью JRE. Это вымышленный компьютер, который реализуется путем имитации различных компьютерных функций на реальном компьютере. JVM имеет собственную полную аппаратную архитектуру, такую как процессор, стек, регистры и т. д., а также соответствующую систему инструкций. Наиболее важной особенностью языка Java является то, что он работает на разных платформах. JVM используется для поддержки независимой от операционной системы кроссплатформенности.
3: принцип JVM
JVM — это ядро и основа Java, виртуальный процессор между компилятором Java и платформой ОС. Это абстрактный компьютер, реализованный программным методом на основе базовой операционной системы и аппаратной платформы, и может выполнять на нем программы байт-кода Java.
Пока компилятор java ориентирован на JVM, он генерирует файлы кода или байт-кода, понятные JVM. Исходные файлы Java компилируются в программы байт-кода, и каждая инструкция транслируется в машинный код для разных платформ с помощью JVM и выполняется на определенной платформе.
4: Архитектура JVM
Загрузчик классов (ClassLoader) (используется для загрузки файлов .class)
Механизм выполнения (выполнение байт-кода или выполнение собственных методов)
Область данных времени выполнения (область методов, куча, стек Java, регистр ПК, собственный стек методов)
5: Область данных времени выполнения JVM
Блок 1: Регистрация ПК
Регистр ПК используется для хранения инструкций JVM, которые каждый поток будет выполнять следующим.Если метод является родным, в регистре ПК информация не сохраняется.
Второй блок: стек JVM
Стек JVM является частным для потока. При создании каждого потока создается стек JVM. В стеке JVM хранятся локальные переменные базового типа в текущем потоке (восемь основных типов, определенных в java: boolean, char, byte, short, int, long, float, double), результаты частичного возврата и Stack Frame, объекты небазовых типов хранят только адрес, указывающий на кучу в стеке JVM.
Третий блок: куча
Это область, используемая JVM для хранения экземпляров объектов и значений массива.Можно считать, что здесь выделяется память всех объектов, созданных new в Java, а память объектов в куче должна ждать GC быть восстановлены.
(1) Куча совместно используется всеми потоками в JVM, поэтому выделение объектной памяти в ней должно быть заблокировано, что также приводит к относительно большим накладным расходам для новых объектов.
(2) Чтобы повысить эффективность выделения объектной памяти, Sun Hotspot JVM выделяет независимое пространство TLAB (Thread Local Allocation Buffer) для созданного потока, размер которого рассчитывается JVM в соответствии с текущей ситуацией, и выделяет объекты на TLAB Нет необходимости в блокировке, поэтому JVM попытается выделить память на TLAB при выделении памяти для объектов потока.В этом случае производительность выделения объектной памяти в JVM в основном так же эффективна, как C, но если объект слишком big по-прежнему выделяется напрямую, используя пространство кучи
(3) TLAB действует только в Eden Space нового поколения, поэтому при написании программ на Java обычно эффективнее выделять несколько небольших объектов, чем большие.
(4) Все вновь созданные объекты будут храниться в новом поколении Yong Generation. Если данные Young Generation переживут один или несколько GC, они будут переданы в OldGeneration. Новые Объекты всегда создаются в Пространстве Эдема.
Блок 4: Область метода
(1) В Sun JDK эта область соответствует PermanentGeneration, также известной как постоянное создание.
(2) В области методов хранится загруженная информация о классе (имена, модификаторы и т. д.), статические переменные в классе, константы, определенные как окончательные типы в классе, информация о полях в классе и информация о методах в классе. получать информацию с помощью таких методов, как getName и isInterface в объекте класса в программе, все эти данные поступают из области методов, и область методов также используется глобально. При определенных условиях это также будет GC. Когда область методов need Сообщение об ошибке OutOfMemory выдается, когда используемый объем памяти превышает допустимый размер.
Блок 5: Пул констант времени выполнения
Фиксированная константная информация, справочная информация о методе и поле в классе сохраняются, а его пространство выделяется из области метода.
Блок 6: Стеки нативных методов
JVM использует собственный стек методов для поддержки выполнения собственных методов.Эта область используется для хранения состояния каждого вызова собственного метода.
6: Алгоритм определения того, что объект «умер»
Поскольку счетчик программ, стек виртуальной машины Java и собственный стек методов являются эксклюзивными для потока, занимаемая ими память также создается вместе с потоком и освобождается, когда поток завершается. Область кучи и методов Java отличается, совместное использование потоков является частью рассматриваемой части GC.
Почти все объекты существуют в куче, перед GC нужно учитывать, какие объекты еще живы и не могут быть переработаны, а какие мертвы и могут быть переработаны.
Существует два алгоритма определения того, является ли объект живым:
1.) Алгоритм подсчета ссылок: добавьте к объекту счетчик ссылок. Всякий раз, когда объект применяется в одном месте, счетчик увеличивается на 1; когда ссылка недействительна, счетчик уменьшается на 1; когда счетчик равен 0, это означает, что объект мертв и подлежит переработке. Но трудно решить случай взаимной циклической ссылки между двумя объектами.
2.) Алгоритм анализа достижимости: Через ряд объектов, называемых «GC Roots» в качестве отправной точки, поиск начинается с этих узлов, а путь, пройденный поиском, называется цепочкой ссылок.Когда объект не имеет никакого GC Корни Если цепочка ссылок подключена (то есть объект недоступен для корней GC), это доказывает, что объект мертв и подлежит переработке. Объекты, которые можно использовать в качестве корней GC в Java, включают: объекты, на которые ссылаются в стеке виртуальной машины, объекты, на которые ссылаются собственные методы в локальном стеке методов, объекты, на которые ссылаются статические атрибуты в области методов, и объекты, на которые ссылаются константы в области методов. .
В основной реализации основных коммерческих языков программирования (таких как наша Java) алгоритм анализа достижимости используется для определения того, жив ли объект.
7: Сборка мусора JVM
Основной принцип GC (сборка мусора): перерабатывать объекты, которые больше не используются в памяти. Метод, используемый для утилизации в GC, называется сборщиком. Поскольку GC требует некоторых ресурсов и времени, Java находится в характеристиках жизненного цикла После анализа объекты собираются в соответствии с новым поколением и старым поколением, чтобы максимально сократить паузу, вызванную GC для приложения.
(1) Набор объектов в новом поколении называется минорным GC;
(2) Коллекция объектов в старом поколении называется Full GC;
(3) Сборщик мусора, принудительно выполняемый активным вызовом System.gc() в программе, является полным сборщиком мусора.
Различные типы ссылок на объекты собираются сборщиком мусора по-разному.Ссылки на объекты JVM делятся на четыре типа:
(1) Сильная ссылка: по умолчанию объект использует сильную ссылку (экземпляр этого объекта не имеет других ссылок на объекты, и он будет переработан только во время GC)
(2) Мягкая ссылка: Мягкая ссылка — это приложение, представленное на Java, которое больше подходит для сценариев кэширования (это будет GC только при нехватке памяти).
(3) Слабая ссылка: она будет переработана GC во время GC
(4) Виртуальная ссылка: поскольку виртуальная ссылка используется только для того, чтобы узнать, является ли объект GC
8. Алгоритмы сборки мусора
1. Алгоритм маркировки-развертки
Самый простой алгоритм делится на два этапа: маркировка и очистка: сначала отмечаются объекты, которые необходимо восстановить, а после завершения маркировки все отмеченные объекты равномерно восстанавливаются.
У него есть два недостатка: один — проблема эффективности, процессы маркировки и очистки неэффективны; один — проблема места, после маркировки и очистки большое количество прерывистых фрагментов памяти (аналогично фрагментации диска нашего компьютера) генерируется, и слишком большая фрагментация пространства приведет к тому, что когда необходимо выделить большой объект, он не сможет найти достаточно непрерывной памяти и должен будет раньше инициировать другую сборку мусора.
2. Алгоритм репликации
Для решения проблемы эффективности появляется алгоритм «копирования», который делит доступную память на два блока равного размера по емкости, и должен использовать только один из них за раз. Когда блок памяти израсходован, скопируйте уцелевшие объекты в другой блок, а затем очистите только что израсходованное пространство памяти. Это решает проблему фрагментации памяти, но платой за это является то, что доступный контент уменьшается вдвое.
3. Алгоритм маркировки-сопоставления
Алгоритм репликации будет выполнять частые операции репликации, когда показатель выживаемости объекта высок, а эффективность будет снижена. Поэтому существует алгоритм очистки меток.Процесс маркировки аналогичен алгоритму очистки меток, но на последующих шагах вместо непосредственной очистки объектов все уцелевшие объекты перемещаются в одну сторону, а затем память вне конечной границы непосредственно очищается.
4. Алгоритм сбора поколений
Текущий GC коммерческих виртуальных машин использует алгоритм сбора поколений. Этот алгоритм не имеет никаких новых идей. Вместо этого куча делится на: новое поколение и старое поколение в соответствии с различными жизненными циклами объекта. Область метода называется постоянное поколение (в новой версии от постоянного поколения отказались и была введена концепция метапространства. Постоянное поколение использует память JVM, а метапространство напрямую использует физическую память).
Таким образом, можно использовать различные алгоритмы сбора в соответствии с характеристиками каждого возраста.
Объекты в новом поколении "живут и умирают". Каждый раз, когда происходит GC, погибает большое количество объектов, а выживает малое. Используется алгоритм репликации. Новое поколение разделено на область Эдема и область выжившего (выживший из, выживший в), а соотношение размеров по умолчанию составляет 8: 1: 1.
Объекты в старом поколении используют алгоритмы маркировки-развертки или маркировки-сортировки, потому что они имеют высокую степень выживания объектов и не имеют дополнительного места для гарантированного размещения.
Вновь сгенерированные объекты первыми попадают в область Эдема.Когда область Эдема заполнена, используется Survivor from.Когда Survivor from также заполнен, выполняется Minor GC (GC нового поколения), и уцелевшие объекты в Eden и Survivor from копируются в Survivor to , а затем пустые Eden и Survivor from.В это время первоначальный Survivor from становится новым Survivor to, а первоначальный Survivor to становится новым Survivor from. При копировании, если Выживший не может вместить все уцелевшие объекты, скопировать объекты в старость согласно гарантии распределения старости (по аналогии с кредитной гарантией банка), а если старость не может вместить, то выполнить Полный GC (старое поколение GC).
Большие объекты входят в старость напрямую: в JVM есть конфигурация параметра -XX:PretenureSizeThreshold, которая заставляет объекты больше, чем это значение параметра, входить в старость напрямую, чтобы избежать копирования большого объема памяти между Eden и Survivor. области.
Долгоживущие объекты вступают в старость: JVM определяет счетчик возраста объекта для каждого объекта.Если объект все еще жив после рождения Эдема и после первого Minor GC и может быть размещен Выжившим, он будет перемещен в Выживший и возраст установлены на 1. Если он не пережил Minor GC, его возраст увеличивается на 1. Когда его возраст достигает определенного уровня (по умолчанию 15 лет, который можно установить с помощью XX:MaxTenuringThreshold), он переходит к старости. Однако JVM не всегда требует, чтобы возраст достиг максимального возраста для перехода к старому поколению.Если сумма размеров всех объектов одного возраста в пространстве оставшихся в живых (например, возраст равен x) больше половины Survivor, все объекты с возрастом больше или равным x переходят в старое поколение напрямую, не дожидаясь достижения максимального возраста.
9: Сборщик мусора
Алгоритм сборки мусора — это методология, а сборщик мусора — конкретная реализация. Спецификация JVM не содержит регламента реализации сборщика мусора, поэтому сборщики мусора, предоставляемые разными производителями и разными версиями виртуальных машин, сильно различаются, здесь мы рассматриваем только виртуальную машину HotSpot.
После JDK7/8 все сборщики и комбинации (подключения) виртуальной машины HotSpot следующие:
1. Серийный коллектор
Коллектор Serial — это самый простой и самый старый коллектор, который когда-то был единственным выбором для мобильных телефонов нового поколения. Он однопоточный и использует только один ЦП или один поток сбора для завершения работы по сбору мусора, а когда он собирает, он должен приостановить все остальные рабочие потоки до его завершения, то есть «Остановить мир». Остановка всех пользовательских потоков неприемлема для многих приложений. Например, когда вы что-то делаете, и другие вынуждены остановиться, можете ли вы сосчитать «альпаки», которые мчатся сквозь ваше сердце?
Тем не менее, он по-прежнему является сборщиком данных молодого поколения по умолчанию для виртуальных машин, работающих в клиентском режиме: простой и эффективный (по сравнению с одним потоком других сборщиков, поскольку отсутствуют накладные расходы на переключение потоков и т. д.).
Рабочая схема:
2.ПарНовый коллектор
Сборщик ParNew — это многопоточная версия сборщика Serial.За исключением использования нескольких потоков, другие функции (алгоритм сбора, остановка мира, правила размещения объектов, стратегии повторного использования и т. д.) такие же, как у сборщика Serial.
Это предпочтительный сборщик нового поколения для многих JVM, работающих в режиме сервера.Одна из важных причин заключается в том, что, за исключением Serial, только он может работать с сборщиком CMS старого поколения.
Рабочая схема:
3. Параллельный сборщик мусора
Сборщик молодого поколения, параллельный многопоточный сборщик. Его целью является достижение контролируемой пропускной способности (то есть отношение времени, в течение которого ЦП выполняет пользовательский код, к общему времени использования ЦП, то есть пропускная способность = время для строк пользовательского кода/[время для строк пользовательского кода + мусор время сбора]), таким образом, процессорное время может быть эффективно использовано, а рабочие задачи программы могут быть выполнены как можно быстрее, что подходит для задач, не требующих слишком большого взаимодействия в фоновой операции.
4. Серийный Старый коллекционер
Старая версия последовательного сборщика, однопоточный, алгоритм «помеченный и отсортированный», в основном для использования виртуальными машинами в клиентском режиме.
Кроме того, в режиме сервера:
Используйте со сборщиком Parallel Scavenge в версиях до JDK 1.5.
Его можно использовать в качестве серверного решения для CMS, а также в случае сбоя параллельного режима в CMS.
Рабочая схема:
5. Параллельный старый коллектор
Старая версия Parallel Scavenge, многопоточного алгоритма «сортировки по меткам», который появился только в JDK 1.6. До этого Parallel Scavenge можно было использовать только с Serial Old.Из-за низкой производительности Serial Old невозможно было реализовать преимущества Parallel Scavenge, что смущает~~
С появлением коллектора Parallel Old коллектор с приоритетом пропускной способности наконец-то получил настоящую комбинацию. Комбинация Parallel Scavenge/Parallel Old может использоваться как в ситуациях, чувствительных к пропускной способности, так и к ЦП. совместная работаСхематическая диаграмма выглядит следующим образом:
6. Сборщик CMS
Сборщик CMS (Concurrent Mark Sweep) — это сборщик, целью которого является получение кратчайшего времени паузы для восстановления.Время паузы короткое, а взаимодействие с пользователем хорошее.
На основе алгоритма «маркировка-развертка», одновременный сбор, низкая пауза, сложный процесс работы, разделенный на 4 этапа:
1) Начальная разметка:Отмечайте только объекты, с которыми GC Roots может напрямую ассоциироваться, что быстро, но требует «Остановить мир».
2) Параллельная маркировка:Это процесс отслеживания цепочки ссылок, который может выполняться одновременно с пользовательским потоком.
3) Переименовать:Исправьте запись маркировки части объекта, маркировка которой изменяется из-за того, что пользовательский поток продолжает работать в параллельной фазе маркировки, которая длиннее, чем начальное время маркировки, но намного короче, чем параллельное время маркировки, требуя «Остановить мир».
4) Параллельный клиринг:Очистить объекты, помеченные как пригодные для повторного использования, и могут выполняться одновременно с пользовательскими потоками.
Поскольку одновременная маркировка и одновременная очистка, которые занимают больше всего времени во всем процессе, могут работать вместе с пользовательским потоком, в общем случае процесс восстановления памяти сборщика CMS и пользовательский поток выполняются одновременно.
Рабочая схема:
Сборщик CSM имеет 3 недостатка:
1) Очень чувствителен к ресурсам процессора
Хотя параллельный сбор не приостанавливает пользовательские потоки, он все равно замедляет работу приложения и снижает общую пропускную способность, поскольку он занимает часть ресурсов ЦП.
По умолчанию число потоков сбора CMS равно (количество ЦП + 3)/4; когда количество ЦП больше 4, поток сбора занимает более 25% ресурсов ЦП, что может иметь большее влияние на программа пользователя, когда меньше 4, влияние больше, может быть неприемлемым.
2) Не справляется с плавающим мусором(Во время параллельной очистки мусор, вновь сгенерированный пользовательским потоком, называется плавающим мусором), может произойти сбой «Сбой параллельного режима».
Определенный объем памяти должен быть зарезервирован для одновременной очистки, и его нельзя собрать, когда он почти заполнен в старости, как другие сборщики; если объем памяти, зарезервированный CMS, не может удовлетворить потребности программы, Произойдет сбой «Сбой параллельного режима»; в это время JVM активирует план резервного копирования: временно включите сборщик Serail Old, что приведет к другому созданию полного GC;
3) Генерировать много фрагментации памяти:CMS основана на алгоритме «разметка-разметка», и большое количество прерывистых фрагментов памяти генерируется без операции сжатия после очистки, что приведет к невозможности найти достаточное количество непрерывной памяти при выделении больших объектов памяти, поэтому еще один Full GC действие должно быть инициировано заранее.
7. Коллектор G1
G1 (Garbage-First) — коммерческий сборщик, официально запущенный в JDK7-u4. G1 — это сборщик мусора для серверных приложений. Его миссия — заменить сборщик CMS в будущем.
Особенности коллекционера G1:
Параллелизм и параллелизм: он может в полной мере использовать аппаратные преимущества многопроцессорных и многоядерных сред и сокращать время паузы; он может выполняться одновременно с пользовательскими потоками.
Поколенческая коллекция:G1 может независимо управлять всей кучей без сотрудничества с другими сборщиками мусора и использует различные методы для обработки новых объектов и объектов, которые сохранились в течение определенного периода времени.
Пространственная интеграция:Алгоритм сортировки по меткам используется целиком, а алгоритм копирования (между двумя областями) используется локально, фрагментации памяти не будет, и GC не будет срабатывать заранее, потому что большие объекты не могут найти достаточно непрерывного пространства, это лучше. чем CMS collection.device.
Предсказуемые паузы:В дополнение к погоне за низкими паузами также может быть установлена предсказуемая модель времени паузы, позволяющая пользователям явно указать, что на временном отрезке длиной M миллисекунд время, затрачиваемое на сборку мусора, не превышает N миллисекунд, что лучше, чем сборщик CMS.
Почему предсказуемая пауза?
Это связано с тем, что можно спланировать, чтобы избежать полной сборки мусора во всей куче Java.
Коллектор G1 делит память на независимые регионы (Regions) одинакового размера, при этом понятия нового поколения и старого поколения сохраняются, но уже не изолированы физически.
G1 отслеживает каждый регион, чтобы получить значение его коллекции, и поддерживает список приоритетов в фоновом режиме;
Каждый раз, в соответствии с разрешенным временем сбора, регион с наибольшим значением будет утилизирован первым (происхождение названия Garbage-First);
Это гарантирует, что максимально возможная эффективность сбора может быть достигнута в течение ограниченного времени.
Что делать, если на объект ссылается объект другого региона?
При оценке выживаемости объекта нам нужно сканировать всю кучу Java, чтобы обеспечить точность? В сборщиках других поколений тоже есть такая проблема (причем G1 более заметная): Нужно ли сканировать старое поколение при сборе молодого поколения? Независимо от G1 или сборщиков других поколений, JVM использует запомненный набор, чтобы избежать глобального сканирования: каждый регион имеет соответствующий запомненный набор; каждый раз, когда записываются данные ссылочного типа, будет создан барьер записи для временного прерывания операции; затем проверьте находится ли объект, на который указывает ссылка, которая должна быть записана, в другом регионе, отличном от данных типа ссылки (другие сборщики: проверьте, ссылается ли объект старого поколения на объект нового поколения); если отличается, запишите соответствующую справочную информацию в ссылку указанный объект через CardTable Запомненный, соответствующий региону, в котором в комплекте;Когда выполняется сборка мусора, добавление Remembered Set в диапазон перечисления корневого узла GC может гарантировать, что не будет выполняться глобальное сканирование и не будет пропусков.
Не считая операции по поддержанию Запоминаемого Набора, процесс утилизации можно разделить на 4 этапа (аналогично CMS):
1) Начальная отметка: отметьте только те объекты, с которыми GC Roots может напрямую ассоциироваться, и измените значение TAMS (следующая вершина при отметке начала), чтобы при одновременном выполнении пользовательской программы на следующем этапе новые объекты могли создаваться в правильный и доступный регион. "Stop The World"
2) Параллельная маркировка: Запустите анализ достижимости из GC Roots, чтобы найти выжившие объекты, что занимает много времени и может выполняться одновременно с пользовательскими потоками.
3) Окончательная метка: исправьте запись метки той части объекта, метка которой изменена, поскольку пользовательский поток продолжает выполняться в параллельной фазе метки. Во время параллельной маркировки виртуальная машина записывает изменения объекта в потоке «Журналы запоминания набора». время, требующее «Остановить мир»
4) Проверка и переработка: сначала отсортируйте стоимость и стоимость переработки для каждого региона, затем настройте план утилизации в соответствии с ожидаемым пользователем временем паузы GC и, наконец, переработайте некоторые объекты мусора в регионах с высокой ценностью в соответствии с планом. Алгоритм репликации используется при рециркуляции, копировании уцелевших объектов из одного или нескольких регионов в другой пустой регион в куче, а также при сжатии и освобождении памяти в процессе; он может выполняться одновременно, сокращая время паузы и увеличивая пропускную способность.
Рабочая схема:
10: Базовая структура
Из логической структуры платформы Java мы можем понять JVM на следующем рисунке:
На приведенном выше рисунке вы можете ясно увидеть различные логические модули, содержащиеся в платформе Java, а также понять разницу между JDK и JRE.
Статья немного длинная, все думают, что авторское резюме в порядке, вы можете щелкнуть QR-код ниже, чтобы следовать. В публичном аккаунте «Java Rotten Pigskin» рассказывается не только о технических знаниях Java, но также об интервью и других галантереях, а на более позднем этапе есть много архитектурной галантереи. Давайте обратим внимание вместе! Обратите внимание на гнилую свиную кожу, дальше будете знать........