Сборка мусора Java 7 (JDK 7) и документация по G1

82

Java 7 уже давно отсутствует, но я не могу найти никаких хороших ресурсов по настройке сборщиков мусора , особенно нового сборщика G1 .

Мои вопросы:

  1. Является ли G1 сборщиком по умолчанию в Java 7, и если нет, как мне активировать G1?
  2. Какие дополнительные настройки есть у g1 в Java7?
  3. Были ли внесены какие-либо изменения в другие сборщики, такие как cms или параллельный сборщик в Java 7?
  4. Где найти хорошую документацию по сборке мусора в Java 7?
Флоракель
источник
6
Приступая к работе со сборщиком мусора G1, также дает хороший обзор передовых методов.
John McCarthy

Ответы:

47

Сборщик мусора G1 не установлен по умолчанию в моей установке Java версии 1.7.0_01. Вы можете убедиться в этом сами, используя некоторые дополнительные параметры командной строки:

> java -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -version
-XX:InitialHeapSize=132304640 -XX:MaxHeapSize=2116874240 -XX:ParallelGCThreads=4 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
java version "1.7.0_01"
Java(TM) SE Runtime Environment (build 1.7.0_01-b08)
Java HotSpot(TM) 64-Bit Server VM (build 21.1-b02, mixed mode)
Heap
 PSYoungGen      total 37696K, used 1293K [0x00000007d5eb0000, 0x00000007d88c0000, 0x0000000800000000)
  eden space 32320K, 4% used [0x00000007d5eb0000,0x00000007d5ff3408,0x00000007d7e40000)
  from space 5376K, 0% used [0x00000007d8380000,0x00000007d8380000,0x00000007d88c0000)
  to   space 5376K, 0% used [0x00000007d7e40000,0x00000007d7e40000,0x00000007d8380000)
 PSOldGen        total 86144K, used 0K [0x0000000781c00000, 0x0000000787020000, 0x00000007d5eb0000)
  object space 86144K, 0% used [0x0000000781c00000,0x0000000781c00000,0x0000000787020000)
 PSPermGen       total 21248K, used 2032K [0x000000077ca00000, 0x000000077dec0000, 0x0000000781c00000)
  object space 21248K, 9% used [0x000000077ca00000,0x000000077cbfc288,0x000000077dec0000)

Тем не менее, вам больше не нужно включать экспериментальные параметры, чтобы включить сборщик G1:

> java -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseG1GC -version
-XX:InitialHeapSize=132304640 -XX:MaxHeapSize=2116874240 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedOops -XX:+UseG1GC -XX:-UseLargePagesIndividualAllocation
java version "1.7.0_01"
Java(TM) SE Runtime Environment (build 1.7.0_01-b08)
Java HotSpot(TM) 64-Bit Server VM (build 21.1-b02, mixed mode)
Heap
 garbage-first heap   total 130048K, used 0K [0x000000077ca00000, 0x0000000784900000, 0x00000007fae00000)
  region size 1024K, 1 young (1024K), 0 survivors (0K)
 compacting perm gen  total 20480K, used 2032K [0x00000007fae00000, 0x00000007fc200000, 0x0000000800000000)
   the space 20480K,   9% used [0x00000007fae00000, 0x00000007faffc288, 0x00000007faffc400, 0x00000007fc200000)
No shared spaces configured.

Не знаю, где найти хорошую документацию.

Кэри
источник
2
Это все еще актуально для 1.7.0_09 на OSX
Age Mooij,
Неправда для Oracle JDK 7u17 на linux / amd64, загруженного непосредственно с веб-сайта Oracle. Это говорит -XX:+UseParallelGC.
user1050755
31

Наконец, Oracle сделала G1 официальным в Java 7 U4: http://www.oracle.com/technetwork/java/javase/7u4-relnotes-1575007.html

Описание: http://docs.oracle.com/javase/7/docs/technotes/guides/vm/G1.html

Параметры командной строки: http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html#G1Options

Тем не менее, я не думаю, что это сборщик по умолчанию в Java 7. Для серверов по умолчанию используется параллельный сборщик, как в Java 6.

Флоракель
источник
1
и сервер определяется 2 ядрами и 2 ГБ оперативной памяти или более. Подробности можно найти на странице hg.openjdk.java.net/jdk7u/jdk7u/hotspot/file/0d82bf449a61/src - посмотрите файлы ./share/tools/launcher/java.c и ./share/vm/runtime/ os.cpp
user1050755
22

Да, G1 - это новый стандартный сборщик мусора в Java 1.7 JVM.

Здесь вы можете найти много информации о том, как использовать и настроить новый сборщик мусора:

Использование G1 G1 по-прежнему считается экспериментальным, и его можно включить с помощью следующих двух параметров:

-XX: + UnlockExperimentalVMOptions -XX: + UseG1GC

Чтобы установить целевое время паузы сборщика мусора, используйте следующий параметр:

-XX: MaxGCPauseMillis = 50 (для целевого времени паузы 50 мс)

С помощью G1 можно указать временной интервал, в течение которого пауза GC не должна длиться дольше указанного выше времени:

-XX: GCPauseIntervalMillis = 200 (для целевого интервала паузы 200 мс)

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

В качестве альтернативы, размер молодого поколения можно указать явно, чтобы повлиять на время перерывов в эвакуации:

-XX: + G1YoungGenSize = 512m (для молодого поколения 512 мегабайт)

G1 также использует эквивалент выживших пространств, которые, естественно, представляют собой набор (потенциально несмежных) регионов. Их размер можно указать с помощью обычных параметров (например, -XX: SurvivorRatio = 6).

Наконец, чтобы запустить G1 в полную силу, попробуйте установить эти два параметра, которые в настоящее время отключены по умолчанию, поскольку они могут выявить редкое состояние гонки:

-XX: + G1ParallelRSetUpdatingEnabled -XX: + G1ParallelRSetScanningEnabled

Еще одна вещь, на которую следует обратить внимание, это то, что G1 очень подробный по сравнению с другими GC HotSpot, когда установлен -XX: + PrintGCDetails. Это потому, что он печатает тайминги для каждого потока GC и другую информацию, очень полезную при профилировании и устранении неполадок. Если вам нужен более краткий журнал GC, переключитесь на использование -verbosegc (хотя рекомендуется получить более подробный журнал GC).

Я также нашел эту статью очень полезной в понимании сути G1.

Еще больше информации здесь .

Войтек Овчарчик
источник
6
Я видел эти ресурсы. Но первая статья посвящена G1 в JDK 6, когда он был еще экспериментальным вариантом. Остальные статьи посвящены бета-версиям JDK 7 возрастом не менее 1 года. Мне нужна более свежая информация или официальная документация от Oracle или команды JDK.
Florakel
13

1. Является ли G1 сборщиком по умолчанию в Java 7 (...)

Правило на этой странице Java 5 все еще применимо в Java 7 (и AFAIK, Java 8):

На машинах серверного класса, на которых работает серверная виртуальная машина, сборщик мусора (GC) был изменен с предыдущего последовательного сборщика (-XX: + UseSerialGC) на параллельный сборщик (-XX: + UseParallelGC).

Но также учтите:

  • 64-битные JVM не имеют -client виртуальной машиной, поэтому всегда являются «серверным классом».
  • Начиная с Java 7, использование -XX: + UseParallelGC (установленное или подразумеваемое) дополнительно подразумевает -XX: + UseParallelOldGC (т.е. если явно не отключено)

Например, если в Windows x64 вы запускаете ...

  • 64-разрядная версия Java 7, по умолчанию вы получаете Parallel GC (как для молодого, так и для старого поколения).
  • 32-разрядная версия Java 8, по умолчанию вы получаете Serial GC (для обоих поколений)

1. (...) как мне активировать G1?

Начиная с Java 7, просто -XX:+UseG1GC. Возможно, также представляет интерес, когда вы захотите:

Приложения, работающие сегодня с CMS или сборщиком мусора ParallelOld, выиграют от перехода на G1, если приложение имеет одну или несколько из следующих характеристик.

  • Более 50% кучи Java занято живыми данными.
  • Скорость размещения или продвижения объекта значительно различается.
  • Нежелательные длительные паузы сборки или уплотнения мусора (от 0,5 до 1 секунды)

2. Какие дополнительные настройки есть у g1 в Java7?

Я сам не использовал G1, но полагаю, что он придерживается тех же основных флагов «пропускной способности / эргономичности», которые используются для настройки других параллельных коллекторов. По моему опыту работы с параллельным сборщиком мусора,-XX:GCTimeRatio он был ключевым в обеспечении ожидаемого компромисса между скоростью и памятью. YMMV.

Параметры, специфичные для G1, перечислены здесь

3. Были ли изменения в (...) cms или параллельном сборщике в Java 7?

Не знаю, но ...

G1 планируется в качестве долгосрочной замены Concurrent Mark-Sweep Collector (CMS)

4. Где найти хорошую документацию по сборке мусора в Java 7?

Это может быть сложно найти, не так ли? Вероятно, лучшая страница "хаба", которую я нашел, это следующая:

http://www.oracle.com/technetwork/java/javase/tech/index-jsp-140228.html

Требуется некоторое глубокое чтение, но оно того стоит, если вам нужно немного настроить. Особенно интересно: Эргономика сборщика мусора.

Люк Ашервуд
источник
13
  1. Является ли G1 сборщиком по умолчанию в Java 7, и если нет, как мне активировать G1?

G1 не является сборщиком по умолчанию в Java 7. -XX:+UseG1GCвключит G1GC.

  1. Какие дополнительные настройки есть у g1 в Java7?

Много. Взгляните на эту статью оракула для получения полной информации.

G1 GC - это адаптивный сборщик мусора со значениями по умолчанию, которые позволяют ему эффективно работать без изменений.

По этой причине настройте критические параметры

-XX:MaxGCPauseMillis
-XX:G1HeapRegionSize
-XX:ParallelGCThreads
-XX:ConcGCThreads

и оставьте все остальные параметры по умолчанию .

Вот список важных параметров и их значений по умолчанию. Этот список относится к последней виртуальной машине Java HotSpot, сборка 24. Вы можете адаптировать и настроить параметры G1 GC в командной строке JVM.

Важные значения по умолчанию:

-XX:G1HeapRegionSize=n

Устанавливает размер области G1. Значение будет степенью двойки и может варьироваться от 1 МБ до 32 МБ. Цель состоит в том, чтобы иметь около 2048 регионов в зависимости от минимального размера кучи Java.

-XX:MaxGCPauseMillis=200

Устанавливает целевое значение для желаемого максимального времени паузы. Значение по умолчанию - 200 миллисекунд. Указанное значение не адаптируется к размеру вашей кучи.

-XX:G1NewSizePercent=5

Устанавливает процент использования кучи как минимум для размера молодого поколения. Значение по умолчанию - 5 процентов вашей кучи Java.

-XX:G1MaxNewSizePercent=60

Устанавливает процент размера кучи, который будет использоваться как максимальный для размера молодого поколения. Значение по умолчанию - 60 процентов вашей кучи Java.

-XX:ParallelGCThreads=n

Устанавливает значение рабочих потоков STW. Устанавливает значение n равным количеству логических процессоров. Значение n совпадает с количеством логических процессоров до 8.

Если имеется более восьми логических процессоров, устанавливает значение n приблизительно равным 5/8 логических процессоров. Это работает в большинстве случаев, за исключением более крупных систем SPARC, где значение n может составлять примерно 5/16 логических процессоров.

-XX:ConcGCThreads=n

Устанавливает количество параллельных маркировочных ниток. Устанавливает n примерно равным 1/4 числа параллельных потоков сборки мусора (ParallelGCThreads).

-XX:InitiatingHeapOccupancyPercent=45

Устанавливает порог занятости кучи Java, запускающий цикл маркировки. По умолчанию используется 45% всей кучи Java.

-XX:G1MixedGCLiveThresholdPercent=65

Устанавливает порог занятости для старой области, которая будет включена в смешанный цикл сборки мусора. Заполняемость по умолчанию составляет 65 процентов.

-XX:G1HeapWastePercent=10

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

-XX:G1MixedGCCountTarget=8

Устанавливает целевое количество смешанных сборок мусора после цикла маркировки для сбора старых регионов с не более чем G1MixedGCLIveThresholdPercent живыми данными. По умолчанию 8 смешанных сборок мусора.

-XX:G1OldCSetRegionThresholdPercent=10

Устанавливает верхний предел количества старых регионов, которые должны быть собраны во время цикла смешанной сборки мусора. По умолчанию это 10 процентов кучи Java.

-XX:G1ReservePercent=10

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

Вы перенастроили многие параметры G1GC, которые не требуются, если вы следуете приведенной выше странице документации. Пожалуйста, сверьтесь с приведенными выше рекомендациями, особенно для ParallelGCThreads и ConcGCThreads , которые должны основываться на ядрах вашего процессора. Убрать перенастройку ненужных параметров.

Рекомендации от оракула:

При оценке и настройке G1 GC учитывайте следующие рекомендации:

  1. Размер молодого поколения : Избегайте явной установки размера молодого поколения с помощью -Xmnпараметра или любого другого связанного параметра, например -XX:NewRatio. Фиксация размера молодого поколения отменяет целевое время паузы .

  2. Цели по времени паузы: когда вы оцениваете или настраиваете сборку мусора, всегда существует компромисс между задержкой и пропускной способностью. G1 GC - это инкрементный сборщик мусора с равномерными паузами, но также с большими накладными расходами на потоки приложения. Целевая пропускная способность для G1 GC составляет 90 процентов времени приложения и 10 процентов времени сборки мусора .

  1. Были ли внесены какие-либо изменения в другие сборщики, такие как cms или параллельный сборщик в Java 7?

В Java 7 есть некоторые изменения. Прочтите эту статью.

  1. Где найти хорошую документацию по сборке мусора в Java 7?

Обратитесь к странице документации oracle о gc и соответствующем вопросе SE:

Сборка мусора Java G1 в производстве

Равиндра бабу
источник
3

Нет, G1 не является сборщиком мусора по умолчанию в jdk 1.7.0_02. Сборщик мусора по умолчанию зависит от класса машины. Если машина относится к классу Server, то сборщик мусора по умолчанию - Сборщик пропускной способности. Если машина относится к классу Client, то сборщик мусора по умолчанию - Serial Collector.

Нитан С. Котвал
источник
1
Я не согласен с тем, что это совершенно правильно. Ссылка на Java 5 , все еще действующая. В системе Windows (32/64): по умолчанию запускать Java 32-bit (5..8) >> Serial GC. По умолчанию запускать Java 64-bit (5..6) >> ParallelGC (только для молодых поколений). По умолчанию запускать Java 64-bit (7..8) >> ParallelOldGC (параллельный Young и Old). Ссылка на изменение Java 7 , наконец, «параллельный» сборщик == сборщик «пропускной способности» »
Люк Ашервуд
3
(Резкий ответ на первый и точный ТАК вклад этого человека. Я отмечаю, что это также их последний.)
Люк Ашервуд,
2

Документация, доступная на http://www.oracle.com/technetwork/java/javase/tech/g1-intro-jsp-135488.html (ссылка, предоставленная Wojtek), кажется, единственная официальная ссылка с информацией, но информация кажется устаревшим, поскольку некоторые из упомянутых там флагов были доступны только в тестовых сборках, они больше не существуют в производственных выпусках. Кто-то из Oracle должен предоставить обновленную документацию по G1 GC.

IceMan
источник
0

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

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

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

Золтан Юхас
источник