Подробная виртуальная машина Java — сводка общих проблем JVM

Java JVM алгоритм CMS

【текст】
Отказ от ответственности: эта статья является лишь кратким изложением.Для более подробного ознакомления с jvm вы можете обратиться к моей предыдущей серии статей, особенно к этой: Подробное объяснение виртуальной машины Java 04 - Алгоритмы и типы GC. Эта статья и эта статья были в центре внимания интервью.
Интервью должно задавать ключевые слова:Собрание мусора JVM, механизм загрузки класса.

Сначала нарисуйте ментальную карту каталога этой статьи: (исходный файл рисунка находится в конце этой статьи)

Во-первых, четыре состояния ссылок Java:

Сильная цитата:
Наиболее широко используется. Когда мы обычно пишем код, новый объект сохраняется в памяти кучи, а затем для указания на него используется ссылка, которая является строгой ссылкой.
* Если объект имеет сильную ссылку, сборщик мусора никогда не собирает его *.当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。
Мягкие ссылки:
Если объект имеет только программные ссылки, сборщик мусора не будет утилизировать его при наличии достаточного места в памяти; еслиЕсли места в памяти недостаточно, память этих объектов будет восстановлена.. (Примечание: если памяти недостаточно, ее можно перезапустить в любое время.)
Пока сборщик мусора не соберет его, объект может использоваться программой. Мягкие ссылки могут использоваться для реализации кэшей, чувствительных к памяти.
Слабая ссылка:
Разница между слабой ссылкой и мягкой ссылкой заключается в следующем:Объекты только со слабыми ссылками имеют более короткое время жизни..
* каждый раз, когда выполняется GC, как только будет найден объект только со слабыми ссылками,Независимо от того, достаточно ли текущего места в памяти или нет, его память будет восстановлена.. Однако, поскольку сборщик мусора является потоком с очень низким приоритетом,Объекты, имеющие только слабые ссылки, не обязательно будут обнаружены быстро*.
Фиктивная ссылка:
«Виртуальные ссылки», как следует из названия, существуют только по названию и отличаются от других типов ссылок.Фантомные ссылки не определяют время жизни объекта. Если объект содержит только фантомные ссылки, это то же самое, как если бы он вообще не имел ссылок,Может быть собран сборщиком мусора в любое время.
Виртуальные ссылки в основном используются для отслеживания активности объектов, утилизируемых сборщиком мусора.
Примечание. Для подробного объяснения различных ссылок вы можете обратиться к этому блогу:
Zhang Jun Mailing.blog.51Cto.com/113473/5309...

Во-вторых, разделение памяти в Java:

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

1dca5ecf-0959-46f9-98c0-f92acc31005f

На картинке выше показано состояние jvm во время работы. Специально разделен на следующие 5 областей памяти: (очень важно)
- Счетчик программ: убедитесь, что поток может быть восстановлен в исходное положение выполнения после переключения
- Стек виртуальной машины: (память стека) Выполнение службы метода Java для виртуальной машины: создание кадра стека при вызове метода -> таблица локальных переменных -> локальная переменная, ссылка на объект
- Стек собственных методов: служба собственных методов для выполнения виртуальной машины.
- куча памяти:хранитьвсе новое
- Область метода:Виртуальная память загружена машинаИнформация о классе, постоянная, статическая постоянная, статический методЖдать.
- Константный пул времени выполнения (часть области метода)

их восстановление GC:
в области памятиСчетчик программ, стек виртуальных машин, собственный стек методовэти 3 областиПоскольку поток родился, потоки;кадр стекаКогда метод входит и выходит, операции укладки и помещения в стек выполняются упорядоченным образом, и сколько памяти выделяется в каждом кадре стека, в основном известно, когда определяется структура класса. В этих областях вам не нужно слишком много думать об утилизации, потому что когда метод завершится или завершится поток, память, естественно, будет утилизирована.
Основные объекты, собранные GC: куча Java отличается от области метода. Память, требуемая несколькими классами реализации в интерфейсе, может быть разной, и память, требуемая несколькими ветвями в методе, также может быть разной. Мы можем использовать ее только во время работы программы. .Только в этот период можно узнать, какие объекты будут созданы.Выделение и высвобождение этой части памяти динамические, и GC также фокусируется на этой части памяти.Если в "памяти" задействовано выделение и высвобождение следующие статьи, это относится только к части памяти.

1. Счетчик программ: (приватный поток)

Каждый поток имеет программный счетчик, созданный при создании потока.
Укажите адрес следующей инструкции
При выполнении нативного метода его значение не определено.

Проще говоря, мы знаем, что Java поддерживает многопоточность.Программа сначала выполняет поток A, половину выполнения, затем выполняет поток B, а затем возвращается для выполнения потока A. Как программа запоминает поток A? нить?Где это реализовано? Для этого требуется программный счетчик. следовательно, чтобы восстановить правильную позицию выполнения после переключения потока, каждый поток имеет независимый счетчик программ, которая является "поточно-частной" памятью.

2. Стек виртуальной машины Java: (приватный поток)

каждыйметод называетсясоздасткадр стека, который используется для хранения такой информации, как таблица локальных переменных, стек операций, динамическая ссылка, выход из метода и т. д. В таблице локальных переменных хранятся: основные типы данных и типы ссылок на объекты, известные во время компиляции.
Процесс вызова каждого метода до завершения выполнения соответствует процессу помещения кадра стека в стек на виртуальной машине.
В Спецификации виртуальной машины Java для этой области указаны два исключения:
(1) Если глубина стека, запрошенная потоком, слишком велика и превышает глубину, разрешенную виртуальной машиной, возникает ошибка StackOverFlowError (например, бесконечная рекурсия. Поскольку каждый слой кадров стека занимает определенное пространство и Xss указывает максимальное пространство стека, при превышении этого значения будет сообщено об ошибке)
(2) Стек виртуальной машины можно динамически расширять.Если он расширяется до точки, когда он не может претендовать на достаточное пространство памяти, произойдет OOM.

3. Стек локальных методов:
(1) Стек локальных методов очень похож на стек виртуальной машины Java, разница в том, что стек виртуальной машины Java предназначен для виртуальной машины для выполнения методов java, в то время как локальный стек методов используется виртуальной машиной.Служба собственных методов.
(2) Виртуальная машина Java не требует использования и структуры данных собственного стека методов.Виртуальная машина Sun HotSpot объединяет стек виртуальной машины Java и собственный стек методов в один.
(3) Стек собственных методов также генерирует StackOverFlowError и OutOfMemoryError.

4. Куча Java: куча памяти (совместное использование потоков)
(1) Куча — это самая большая часть области памяти, управляемой виртуальной машиной Java. Куча Java — это область памяти, разделяемая всеми потоками. Она создается при запуске виртуальной машины Java. для хранения почти всех объектов экземпляра объекта.Экземпляры размещаются в куче памяти.
(2)Куча — это основная область, управляемая сборщиком мусора., с точки зрения сборки мусора, поскольку все текущие сборщики мусора используютКоллекция поколенийалгоритм, поэтому куча Java также может быть изначально подразделена наМолодой и старый.
(3) Виртуальная машина Java предусматривает, что куча может находиться в физически прерывистом пространстве памяти, если она логически непрерывна. Реализация может быть фиксированной или динамически расширяемой. Исключение OutOfMemoryError возникает, если выделение экземпляра в памяти кучи не завершено и размер кучи не может быть увеличен.

5. Область метода: (обмен потоками)
(1) Он используется для хранения таких данных, как информация о классе, константы, статические переменные и код, скомпилированный компилятором реального времени, который был загружен виртуальной машиной.
(2) Виртуальная машина Sun HotSpot называет область методов постоянной генерацией, а последняя часть области методов — это постоянный пул времени выполнения.

6, запуск постоянного пула:
(1) Бассейн постоянного времени выполнения является частью области метода, которая, естественно, ограничена памятью области метода. Когда постоянный пул больше не может применяться для памяти, исключение OutofMemoryError будет брошено.

3. Состояние объектов Java в памяти:

достижимый / достижимый:
После создания объекта Java он доступен, если на него ссылается одна или несколько переменных. То есть до объекта можно добраться из корневого узла.
По сути, это сканирование из корневого узла.Пока объект находится в цепочке ссылок, он доступен.
Восстанавливаемый:
Объект Java переходит в восстанавливаемое состояние, когда на него больше не ссылается какая-либо переменная.
Перед повторным использованием объекта метод finalize() объекта выполняет очистку ресурсов. еслиВ методе finalize() пусть переменная снова ссылается на объект, и объект снова становится доступным, иначе объект переходит в недостижимое состояние
Недоступно:
На объект Java не ссылается никакая переменная, и система по-прежнему не делает объект доступным после вызова метода finalize() объекта (на объект по-прежнему не ссылаются переменные), тогда объект станет недоступным.
Когда объект Java находится в недостижимом состоянии, система действительно вернет ресурсы, занятые объектом.

Четыре, два общих алгоритма оценки смерти объекта:

Когда на объект нет ссылки, этот объект умирает, ожидая перезапуска GC.
1. Алгоритм подсчета ссылок:
концепция:
Добавить к объекту счетчик ссылок, при наличии ссылки на него значение счетчика увеличивается на 1, при недействительной ссылке значение счетчика уменьшается на 1, объект, у которого счетчик равен 0, в любой момент времени невозможен использоваться снова.
но:
Основная виртуальная машина Java не использует алгоритм подсчета ссылок для управления памятью по следующим причинам:Трудно решить проблему взаимных циклических ссылок между объектами.
преимущество:
Реализация алгоритма проста, а эффективность суждений высока, в большинстве случаев это хороший алгоритм. применяется к нему во многих местах
недостаток:

Ссылка и разыменование сопровождают сложение и вычитание, влияя на производительность.
Фатальный недостаток: ДляОбъекты с циклическими ссылкамиПереработка невозможна

2. Алгоритм поиска корня:(алгоритм, используемый jvm)
концепция:
Настройте несколько видов корневых объектов.Если какой-либо корневой объект (GC Root) недоступен для определенного объекта, этот объект считается пригодным для повторного использования.
Примечание:Здесь упоминается, что установлено несколько видов корневых объектов.Если какой-либо корневой объект недоступен для определенного объекта, этот объект считается пригодным для повторного использования. Когда мы позже представим алгоритм очистки-маркировки/алгоритм сортировки по маркировке, мы всегда будем подчеркивать, что, начиная с корневого узла, помечаем все достижимые объекты один раз, так что же достижимо?
Анализ доступности:
Начиная с объекта корня (GC Roots) в качестве отправной точки, поиск начинается вниз, и путь, пройденный поиском, называется «GC Roots».цепочка ссылок", когда объект не связан с GC Roots какой-либо цепочкой ссылок (с точки зрения теории графов он недоступен из GC Roots к этому объекту), это доказывает, что этот объект недоступен.

83fbdb3a-6da2-4307-9cc5-63663080c2ce

Как показано на рисунке выше, ObjectD и ObjectE связаны друг с другом, но, поскольку корни GC недостижимы для этих двух объектов, D и E в конечном итоге все равно будут рассматриваться как объекты GC. выше рисунка, то есть пять AE Объекты никогда не перерабатываются.

Корни (GC Корни):
Говоря о GC Roots (корнях GC), в языке Java у вас могут быть следующие объекты GC Roots:

1,куча(таблица локальных переменных в кадре стека)объект, указанный в.
2. Статические элементы в области метода.
3. Объекты (глобальные переменные), на которые ссылаются константы в области методов
4. Объект, на который ссылается JNI (вообще говорящий нативный метод) в стеке локального метода.

Примечание. Первое и четвертое относятся к таблице локальных переменных метода, второе более четко выражает смысл, а третье в основном относится к постоянному значению, объявленному как final.
На основе алгоритма поиска корня, в реализации современных виртуальных машин,Алгоритмы сборки мусораВ основном различают три видаалгоритм маркировки-развертки,алгоритм репликации,алгоритм маркировки-сопоставления. Все три алгоритма расширяют алгоритм поиска корня, но они все еще очень хорошо изучены.

Пять, алгоритм сборки мусора:

1. Алгоритм маркировки-развертки:
концепция:
Фаза маркировки:Сначала передайте корневой узел, отметьте все достижимые объекты, начиная с корневого узла..因此,未被标记的对象就是未被引用的垃圾对象;
Фаза очистки: очищает все неотмеченные объекты.

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

2. Алгоритм репликации: (GC нового поколения)
концепция:
поставь оригиналПространство памяти разделено на два, только один из них используется одновременно, при сборке мусора используемая память будетуцелевший объектКопирует в неиспользуемый блок памяти, затем очищает все объекты в используемом блоке памяти.
преимущество:

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

Минусы: пустая трата места
Из вышеприведенного описания нетрудно увидеть, что для использования алгоритма репликации как минимум выживаемость объекта должна быть очень низкой.
Все сегодняшние коммерческие виртуальные машины используют этот алгоритм сбора для повторного использования нового поколения.98% объектов в новом поколении "уходят и умирают", поэтому нет необходимости делить пространство памяти по соотношению 1:1, ноПамять разделена на большее пространство Эдема и два меньших пространства Выживших., каждый раз используя Эден и одну из фишек Выжившего. При переработке скопируйте уцелевшие объекты в Эдеме и Выжившем в другое пространство Выжившего за один раз и, наконец, очистите Эдем и только что использованное пространство Выжившего. Соотношение размеров Eden и Survivor по умолчанию в виртуальной машине HotSpot составляет 8:1, то есть доступное пространство памяти в каждом новом поколении составляет 90% (80%+10%) от всей емкости нового поколения, и только 10 % площади будет использоваться в качестве отходов.
Конечно, 98% объектов, которые могут быть переработаны, — это только данные в общих сценариях, и мы не можем гарантировать, что не более 10% объектов выживут при каждой переработке.Когда места Survivor недостаточно, ему нужно полагаться на старость для гарантии распределения, поэтому большой объект напрямую входит в старость.. Весь процесс показан на рисунке ниже:

37e28257-008e-40ad-a07f-1a45a38d4be2

3. Алгоритм маркировки-сортировки: (GC в старости)
Алгоритм копирования в объектвысокая выживаемостьКогда требуется больше операций копирования, эффективность будет снижаться, поэтому этот алгоритм нельзя будет напрямую использовать в старом возрасте.
концепция:
Фаза маркировки: сначала пройдите через корневой узел и отметьте все достижимые объекты, начиная с корневого узла. Следовательно, непомеченные объекты являются объектами мусора без ссылок.
завершающий этап:*Сжать все живые объекты в один конец памяти*, после чего очистить все пространство за пределами

преимущество:
Фрагментации памяти не происходит.
недостаток:
На основе маркировки также необходимо перемещать объекты, что относительно дорого и неэффективно.

Их различия заключаются в следующем: (> представляет собой первое превосходит второе, тот же эффект представляют оба =)
(1) Эффективность: Алгоритм репликации>Алгоритм тега/утверждения>Алгоритм тега/Очистить (здесь эффективность здесь заключается только в простой сложности сравнения времени, реальная ситуация не обязательно имеет место).
(2) Однородность памяти: Алгоритм копирования = Алгоритм пометки/упорядочивания > Алгоритм пометки/очистки.
(3) Использование памяти: алгоритм маркировки/сортировки = алгоритм маркировки/развертки > алгоритм копирования.

Примечание 1: Алгоритм сортировки по отметке может не только компенсировать недостатки разбросанной области памяти в алгоритме пометки и очистки, но и устранить высокую стоимость уменьшения вдвое памяти в алгоритме копирования.
Примечание 2: видно, что алгоритм пометки/очистки является относительно обратным алгоритмом, но последние два алгоритма созданы на этой основе.
Примечание 3: Время и пространство не могут иметь и то, и другое.

4. Алгоритм сбора поколений:
Текущая бизнес-виртуальная машина GC — это «независимый алгоритм сбора», это не новая идея,Просто разделите память на несколько частей в соответствии с жизненным циклом объекта. Как правило, куча Java делится на новое поколение и старое поколение:Краткоживущие объекты относятся к молодому поколению, а долгоживущие к старому поколению..
Низкая выживаемость: выживает небольшое количество объектов, подходит для алгоритмов репликации: В новом поколении обнаруживается, что в каждом GC погибает большое количество объектов, а выживают лишь немногие (98% объектов в новом поколении «мертвые»), то используется алгоритм репликации, и только требуется небольшое количество выживших объектов.Скопируйте затраты для завершения GC.
Высокая выживаемость: выживает большое количество объектов, подходит для маркировки-очистки/маркировки-очистки: в старости, поскольку объект имеет высокую выживаемость и нет дополнительного места для его размещения, он должен использовать «маркировку-очистку». чистый"/"отметить-очистить" алгоритм уборки для GC.

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

6. Сборщик мусора:

Если говорить о методологии утилизации памяти в алгоритме сбора, то сборщик мусора — это конкретная реализация утилизации памяти.
Хотя мы сравниваем различные коллекторы, мы не пытаемся выбрать лучший. Потому что до сих пор нет лучшего коллектора, и всемогущий коллектор нет, поэтому мыВыбирается только наиболее подходящий коллектор для конкретного применения.
1. Серийный коллектор: (серийный коллектор)
Этот сборщик является однопоточным сборщиком, но его однопоточное значение означает не только то, что он будет использовать только один ЦП или один поток сбора для завершения работы по сборке мусора, но, что более важно, когда он выполняет сборку мусора, он должен приостанавливать все процессы. другие рабочие потоки (Stop-The-World: приостановить все потоки нормальной работы пользователя.) до конца его сбора. Процесс работы коллектора показан на следующем рисунке:

9012f0bf-fe1b-4e19-a7ec-b5c0e6fb7174
Изображение выше:
- Новое поколение использует алгоритм репликации Stop-The-World
- Старость принимает алгоритм сопоставления меток Stop-The-World

Когда GC работает, хотя это и вызовет Stop-The-World, он существует по какой-то причине: именно из-за своей простоты и эффективности (по сравнению с коэффициентом однопоточности других сборщиков), для одной среды с ограниченным процессором. Другими словами, без накладных расходов на взаимодействие потоков вы естественным образом можете добиться максимальной эффективности однопоточного мобильного телефона, сосредоточившись на сборщике мусора. такSerial Collector — хороший выбор для работы в клиентском режиме.(это все еще виртуальная машина, работающая наВ режиме клиентаДефолтКайнозойколлекционер).

**2, сборщик ParNew: **Многопоточная версия сборщика Serial (с использованием нескольких потоков для GC).
Сборщик ParNew — это многопоточная версия сборщика Serial.
* Это предпочтительный сборщик для молодого поколения, работающий в режиме сервера *, помимо сборщика Serial, на данный момент работает только с сборщиком CMS. Сборщик CMS считается эпохальным параллельным сборщиком, поэтому, если есть сборщик мусора, который можно использовать с ним, чтобы сделать его более совершенным, то этот сборщик тоже должен быть обязательной частью. Процесс работы коллектора показан на следующем рисунке:

852249d2-1be3-4126-8cb7-24909c404e17

Рисунок выше:
- Новое поколение использует алгоритм репликации Stop-The-World
- Старость принимает алгоритм сопоставления меток Stop-The-World

3. ПарНью*Scanvenge*коллекционер
Похоже на ParNew, но большеСосредоточьтесь на пропускной способности.Цель состоит в том, чтобы достичьконтролируемая пропускная способностьколлекционер.
Время паузы и пропускная способность не могут быть настроены одновременно. С одной стороны, мы надеемся, что время паузы будет меньше, а с другой стороны, мы надеемся, что пропускная способность будет высокой, На самом деле это противоречиво. Потому что: при сборке мусора общий объем работы по сборке мусора неизменен, если уменьшить время паузы, то частота увеличится, так как частота увеличена, значит, сборка мусора будет выполняться часто, а пропускная способность уменьшится. будет уменьшен.
пропускная способность: отношение времени ЦП, используемого для пользовательского кода, к общему времени использования ЦП, т.е. = время выполнения пользовательского кода/(время выполнения пользовательского кода + время сборки мусора). Например, если виртуальная машина работает в общей сложности 100 минут, из которых сборка мусора занимает 1 минуту, пропускная способность составляет 99%.

4. Коллектор G1:
Это одно из самых важных достижений в области разработки коллекторов, известное как jdk1.7, солнце, прежде чем компания думает, что оно достигло достаточной степени коммерческой зрелости.
преимущество:
Его самым большим преимуществом является то, что он сочетает в себе пространственную интеграцию, не генерирует много мусора и снижает частоту сбора мусора.
Во-вторых, пользователи могутЯвно указать указанное время паузы. (Вы можете указать минимальное время, по истечении этого времени он не будет переработан)
Одна из причин, по которой это так эффективно: сборка мусораПриоритетные операции были выполненыЭтот приоритетный метод утилизации зоны обеспечивает высокую эффективность.
Если ваше приложение ищет паузу, то теперь можно попробовать G1; если ваше приложение ищет пропускную способность, то G1 не принесет вам особых преимуществ.
Примечание. Все вышеперечисленные сборщики останавливают мир при выполнении сборщика мусора, но следующий сборщик CMS этого не делает.

5. Сборщик CMS: (сборщик старого поколения)
Сборщик CMS (Concurrent Mark Sweep:Параллельная развертка меток) этоСтремитесь получить кратчайшее время паузы на переработкуколлекционер. Он подходит для применения на сервере Интернет-сайта или в системе B / S. Этот тип приложения уделяет особое внимание скорости отклика сервера и надеется, что время паузы системы будет кратчайшим.
Процесс работы коллектора CMS:(акцент на реализацииотметкапроцесс)
(1) Начальная отметка
Объект, к которому корень может быть непосредственно связан
высокоскоростной
(2) Параллельная маркировка (с пользовательскими потоками)
Основной процесс маркировки, маркировка всех объектов
(3) Повторная пометка
Поскольку пользовательский поток все еще работает во время параллельной маркировки, внесите исправления до официальной очистки.
(4) Параллельная очистка (с пользовательскими потоками)
Основываясь на отмеченном результате, очистите объект напрямую
Весь процесс показан на рисунке ниже:

89af7bbc-5331-4c62-ab7e-18e93350f826

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


преимущество:
Параллельный сбор, низкая пауза
недостаток:
(1) Скорость выполнения пользователя снижается.
(2) не может обрабатывать плавающий мусор. Потому что он использует алгоритм метки-развертки. После метки может быть какой-то мусор, сборщику мусора придется подождать, пока следующий не будет переработан. Если вы не можете выполнить программу, которая должна быть запущена во время работы CMS, она временно активирует сборщик старых серийных номеров на старом телефоне.
(3) Поскольку используется алгоритм маркировки-развертки, будет сгенерировано большое количество фрагментов. Часто бывает так, что в старом возрасте еще много места, но он не может найти достаточно большое непрерывное пространство для размещения текущего объекта и должен срабатывать заранее ГК

сомневаться:*Поскольку алгоритм маркировки-очистки может вызвать фрагментацию пространства памяти, почему сборщик CMS использует алгоритм маркировки-очистки вместо алгоритма маркировки-очистки:*
Отвечать:
Сборщик CMS больше заботится о паузах, которыеПри выполнении GC работает с пользовательскими потоками(параллельное выполнение), если вы используете теги для организации алгоритма, то когда будет очищаться место в памяти, доступное для перемещения объекта, тоПоток приложения, скорее всего, не найдет, где находится объект приложения..

Семь, разделение памяти кучи Java:

По степени выживаемости (возрасту) объекта Java делит память на три типа: новое поколение, старое поколение и постоянное поколение:
1. Новое поколение:
Например, если мы перейдем к новому объекту в методе, после вызова метода объект будет переработан, что является типичным объектом нового поколения.
Сегодняшние коммерческие виртуальные машины используют этот алгоритм сбора для повторного использования нового поколения.98% объектов в новом поколении являются «мертвыми», поэтому не нужно делить пространство памяти по соотношению 1:1, аПамять разделена на большее пространство Эдема и два меньших пространства Выживших., каждый раз используя Эден и одну из фишек Выжившего. При переработке скопируйте уцелевшие объекты в Эдеме и Выжившем в другое пространство Выжившего за один раз и, наконец, очистите Эдем и только что использованное пространство Выжившего. Соотношение размеров Eden и Survivor по умолчанию в виртуальной машине HotSpot составляет 8:1, то есть доступное пространство памяти в каждом новом поколении составляет 90% (80%+10%) от всей емкости нового поколения, и только 10 % площади будет использоваться в качестве отходов.
Конечно, 98% объектов, которые могут быть переработаны, — это только данные в общих сценариях, и мы не можем гарантировать, что не более 10% объектов выживут при каждой переработке.Когда места Survivor недостаточно, ему нужно полагаться на старость для гарантии распределения, поэтому большой объект напрямую входит в старость.. в то же время,Долгоживущие объекты войдут в старость (Виртуальная машина определяет счетчик возраста для каждого объекта).
Взгляните на картинку ниже:

ef34e1c5-c6e1-4108-a939-87c9f5de0fff

Незначительный GC и полный GC:
Существует два типа GC: Minor GC и Full GC.
Малый ГК:
Незначительный GC происходит в действии сборки мусора нового поколения с использованием алгоритма копирования.
После рождения объектов в областях Эдем и Из, после Малого GC, если объекты все еще живы и могут быть размещены в области до, эти уцелевшие объекты будут скопированы в область до при использовании алгоритма копирования, и затем Эдем будет зачищать область и из области, и устанавливать возраст этих объектов на 1. После этого каждый раз, когда объект проходит Минор в области Выживший GC увеличит возраст объекта на 1. Когда возраст объекта достигнет определенного значения (по умолчанию 15 лет, что можно установить параметром –XX:MaxTenuringThreshold), эти объекты станут старыми.
Но это не обязательно, для какого-то более крупного объекта (необходимость выделения большого непрерывного пространства памяти) есть прямой доступ к старому году
Полный ГК:
Полный сборщик мусора — это действие по сборке мусора, которое происходит в старости с использованием алгоритма маркировки-очистки/сортировки.
Предметы в старости почти все выжили в зоне Survivor, и так просто не умрут. Поэтому полный GC будет происходить не так часто, как Minor GC, и на выполнение Full GC уйдет больше времени, чем на Minor GC.
Кроме того, если используется алгоритм маркировки-очистки, будет сгенерировано много фрагментов.Если необходимо выделить пространство памяти для более крупных объектов, если не удается найти достаточное непрерывное пространство памяти, сборщик мусора будет запущен заранее.

2. Старость:
Объекты, пережившие N сборок мусора в молодом поколении, будут помещены в старое поколение. А крупные объекты уходят прямо в старость.

3. Постоянное поколение:
Эта область метода.

Восемь, механизм загрузки классов:

Виртуальная машина загружает данные, описывающие класс, из файла Class в память, проверяет, преобразует, анализирует и инициализирует данные и, наконец, формирует тип Java, который может быть непосредственно использован виртуальной машиной.Это механизм загрузки класса. виртуальной машины.
Процесс загрузки класса:
Включая загрузку, линковку (включая проверку, подготовку, парсинг), инициализацию
Как показано ниже:

1. Загрузка:
Загрузка класса относится к чтению файла класса класса в память и созданию файла java.lang.Объект класса, как область методаЗапись для доступа к данным этого класса.
То есть, когда какой-либо класс используется в программе, система создаст для него объект java.lang.Class. В частности, он включает в себя следующие три части:
(1) пройтиполное название классаСоздает поток двоичных данных для соответствующего класса. (Согласно принципу ранней загрузки, если соответствующий файл класса не найден, ошибка будет выброшена только тогда, когда класс действительно используется)
(2) Анализировать и преобразовывать эти потоки двоичных данных в структуры данных, специфичные для области метода.
(3) Создайте объект java.lang.Class соответствующего класса в качестве входа в область методов (с соответствующим объектом класса это не означает, что класс завершил ссылку загрузки)

Используя разные загрузчики классов, двоичные данные класса можно загружать из разных источников, обычно из следующих источников:
(1) Загрузите файл класса из локальной файловой системы, как загружается большинство программ.
(2) Загрузка файла класса из пакета jar также очень распространена.Например, класс, управляемый базой данных, используемый в программировании jdbc, помещается в пакет jar, и jvm может напрямую загружать файл класса из файла jar.
(3) Загрузите файл класса через сеть
(4) Динамически компилировать и загружать исходный файл Java

2. Ссылки:
Связывание относится к процессу включения двоичного файла класса Java в рабочее состояние JVM. Этот класс должен быть успешно загружен перед компоновкой.
Ссылки на классы включаютПроверить, подготовить, разобратьэти три шага. Конкретное описание выглядит следующим образом:
2.1 Проверка:
Проверка используется для того, чтобы гарантировать, что двоичное представление класса Java является полностью правильным по структуре (например, формат файла, синтаксическая семантика и т. д.). Если в процессе проверки возникает ошибка, будет выдана ошибка java.lang.VertifyError.
В основном проверьте следующее:
проверка формата файла
Проверка метаданных: семантическая проверка
Проверка байт-кода

2.2 Подготовка:
Процесс подготовки заключается в создании класса Javaстатическийполя (статическое измененное содержимое) и установите значение этих полей вПо умолчаниюПокаВыделить место в памяти в области метода. Процесс подготовки не выполняет код.
Обратите внимание, что это инициализация по умолчанию, а не явная инициализация. Например:
public static int value = 12;

В приведенном выше коде вэтап подготовки, установит значение value равным 0 (Инициализация по умолчанию). Сзадифаза инициализацииустановит значение value равным 12 (явная инициализация).
2.3 Анализ:
Процесс синтаксического анализа должен гарантировать, что эти ссылочные классы будут найдены правильно (замените символические ссылки прямыми ссылками). Процесс синтаксического анализа может вызвать загрузку других классов Java.

3. Инициализация:
Фаза инициализации является последним шагом в процессе загрузки класса. На этапе инициализации программный код Java (или байт-код), определенный в классе, фактически выполняется.
Процесс инициализации выполняется в следующих ситуациях:

(1) Создайте экземпляр класса
(2) Доступ к статическим переменным класса или интерфейса (Особый случай: если это константа, дополненная static final, класс не будет явно инициализирован. Переменные, измененные static final, будут явно инициализированы)
Статический метод (3) Позвоните в класс
(4) Отражение (Class.forName(packagename.className))
(5) Инициализировать подкласс класса. Примечание. Проблема инициализации подкласса: встретить активный вызов, т.е.Когда родительский класс обращается к статическим переменным и методам в подклассе, подкласс будет инициализирован.; в противном случае инициализируется только родительский класс.
(6) Класс, отмеченный как класс запуска при запуске виртуальной машины Java.

Пример кода 1:
Давайте сделаем пример кода для вышеуказанного (5) случая.
(1)Father.java:

public class Father {

    static {
        System.out.println("*******father init");
    }
    public static int a = 1;
}

(2)Son.java:

 public class Son extends Father {
     static {
         System.out.println("*******son init");
     }
     public static int b = 2;
 }

(3)JavaTest.java:

 public class JavaTest {
     public static void main(String[] args) {
         System.out.println(Son.a);
     }
 }

В приведенном выше тестовом классе, несмотря на то, что используется класс Son, члены подкласса не вызываются, поэтому подкласс не инициализируется. Итак, беговой эффект:

b6de0ab4-1502-46dd-9193-578d1c83ca20

Если вы измените JavaTest.java на следующее:

 public class JavaTest {
     public static void main(String[] args) {
         System.out.println(Son.a);
         System.out.println(Son.b);
     }
 }

текущий результат:

b4757ac3-7476-49ff-84a4-659dca412324

Пример кода 2:

Давайте сделаем пример кода для вышеуказанного (2) случая. То есть: если это константа, украшенная static final, она не будет явно инициализирована. Пример кода выглядит следующим образом:

(1)Father.java:

 public class Father {
     static {
         System.out.println("*******father init");
     }
     public static int a = 1;
 }

(2)Son.java:

/**
 * Java学习交流QQ群:589809992 我们一起学Java!
 */
public class Son extends Father {
    static {
        System.out.println("*******son init");
    }

    public static int b = 2;
    public static final int c = 3;
}

Переменная c здесь является статической константой.

(3)JavaTest.java:

 public class JavaTest {
     public static void main(String[] args) {
         System.out.println(Son.c);
     }
 }

d04e2783-18db-41c4-958d-e9bbee011854

Приведенный выше бегущий эффект показывает, чтоПоскольку c — это статическая константа, модифицированная final static, содержимое в блоке статического кода вообще не вызывается, то есть класс явно не инициализируется..
Пока оставьте код Отца.java без изменений. Измените код Son.java следующим образом:

/**
 * Java学习交流QQ群:589809992 我们一起学Java!
 */
public class Son extends Father {
    static {
        System.out.println("*******son init");
    }

    public static int b = 2;
    public static final int c = new Random().nextInt(3);
}

JavaTest.java:

 public class JavaTest {
     public static void main(String[] args) {
         System.out.println(Son.c);
     }
 }

Эффект операции следующий:

235bc0d9-0b08-436c-9b6d-380702f4a8c7

Пример кода 3: (очень подвержен ошибкам)
Что мы должны запустить следующие результаты кода:

/**
 * Java学习交流QQ群:589809992 我们一起学Java!
 */
public class TestInstance {

    public static TestInstance instance = new TestInstance();
    public static int a;
    public static int b = 0;

    public TestInstance() {
        a++;
        b++;
    }

    public static void main(String[] args) {
        System.out.println(TestInstance.a);
        System.out.println(TestInstance.b);
    }
}

результат операции:

7281067e-8c73-4929-b23a-5b0992f2deff

Причина такого бегущего результата связана с порядком загрузки классов:
(1) На этапе загрузки загрузите информацию о классе
(2) На этапе подготовки ссылки инициализируйте и выделите пространство, например, по умолчанию a и b. В настоящее время значения a и b равны 0.
(3) На этапе инициализации выполняется конструктор, и оба значения a и b равны 1.
(4) На этапе инициализации статическая переменная инициализируется явно, и в это время значение b равно 0.

Изменим порядок выполнения кода на следующий:

public class TestInstance {

    public static int a;
    public static int b = 0;
    public static TestInstance instance = new TestInstance();

    public TestInstance() {
        a++;
        b++;
    }

    public static void main(String[] args) {
        System.out.println(TestInstance.a);
        System.out.println(TestInstance.b);

    }
}

Эффект бега:

e71a9e60-be2c-4072-9602-3fa591e0b940

Причина такого бегущего результата связана с порядком загрузки классов:
(1) На этапе загрузки загрузите информацию о классе
(2) На этапе подготовки ссылки инициализируйте и выделите пространство, например, по умолчанию a и b. В настоящее время значения a и b равны 0.
(3) На этапе инициализации статическая переменная инициализируется явно, и в это время значение b по-прежнему равно 0.
(4) На этапе инициализации выполняется конструктор, и оба значения a и b равны 1.

Обратите внимание, что здесь задействована еще одна похожая точка знаний, так что не путайте ее. Очки знаний следующие.
Точка знаний: процесс инициализации класса (важно)
Что делает Student s = new Student(); в памяти?
- Загрузите файл Student.class в память
- существуетстек памятиосвободить место для с
- существуеткуча памятиОсвободите место для студенческих объектов
- Сделать переменную-член студенческого объектаИнициализация по умолчанию
- Сделать переменную-член студенческого объектаотображение инициализации
- пройти черезМетод строительствадля студенческих объектовназначение переменных-членов
- После того, как объект студента инициализирован, поместитеАдрес объекта присваивается переменной s