Почему полный GC JVM должен остановить мир?
Мне задали этот вопрос, и я просто ответил "потому что JVM нужно перемещать объекты", но позже я погуглил, и, похоже, я не смог найти разумного ответа.
4 ответа
Во-первых, статья "Сборка мусора" в Википедии действительно хороша для чтения.
Кстати, о.
Как правило, сборщик мусора не требует остановки "Остановка мира". Существуют реализации JVM, которые (почти) свободны от пауз (например, Azul Zing JVM). Всякий раз, когда JVM требует, чтобы STW собирал мусор, зависит от алгоритма, который он использует.
Mark Sweep Compact (MSC) - это популярный алгоритм, используемый в HotSpot по умолчанию. Он реализован в стиле STW и имеет 3 этапа:
- MARK - пересечь график живых объектов, чтобы отметить достижимые объекты
- SWEEP - сканирует память, чтобы найти немаркированную память
- COMPACT - перемещение выделенных объектов для дефрагментации свободной памяти
При перемещении объектов в куче JVM должна исправить все ссылки на этот объект. Во время процесса перемещения граф объектов не согласован, поэтому требуется пауза STW.
Concurrent Mark Sweep (CMS) - это еще один алгоритм в HotSpot JVM, который не использует паузу STW для старой коллекции пространства (не совсем то же самое, что полная коллекция).
CMS использует барьер записи (срабатывание триггера каждый раз, когда вы пишете ссылку в куче Java) для реализации параллельной версии MARK и не использует COMPACT. Отсутствие сжатия может привести к фрагментации, и если фоновая сборка мусора не достаточно быстрая, приложение все равно может быть заблокировано. В этих случаях CMS откатится к коллекции STW mark-sweep-compact.
Существует также G1, который является постепенным изменением MSC. Вы можете прочитать больше об алгоритмах GC в HotSpot JVM в моем блоге.
При использовании пропускной способности GC JVM требуется паузы STW, чтобы освободить как можно больше памяти. Это только использование таких пауз, что является наиболее эффективным.
Используя коллектор с низкой паузой (CMS), вы очищаете старое поколение одновременно, не останавливая приложение. Недостатком является то, что старое поколение становится фрагментированным. Если он слишком фрагментирован и нуждается в сжатии, происходит Full GC (STW). Тем не менее, вы всегда можете настроить приложение так, чтобы вы не получали Full GC.
G1 GC - особый случай. В настоящее время его основной целью является низкая фрагментация в куче при одновременной одновременной работе (например, CMS). Когда он не может достичь этой цели, JVM также возвращается к паузе STW, так что куча полностью очищается и уплотняется.
Короткая фаза остановки мира необходима для поиска ссылок в стеке практически в любой схеме сборки мусора, даже в большинстве схем, которые минимизируют паузы. Большое подробное объяснение в этом ответе. инкрементные и параллельные алгоритмы усердно работают, чтобы свести к минимуму эти паузы до минимума, но в большинстве случаев они все же есть.
На самом деле существуют даже методы перемещения / сжатия, которым не нужно останавливать мир во время перемещения объектов (на ум приходит Стаккато)
stop-the-world гарантирует, что новые объекты не будут размещены и объекты не станут внезапно недоступными во время работы сборщика.
Преимущество заключается в том, что он проще и быстрее, чем инкрементная сборка мусора.