Статьи

G1 против CMS против параллельного GC

Этот пост посвящен эксперименту, который мы провели ровно год назад, по сравнению производительности различных алгоритмов GC в реальных условиях. Мы взяли тот же эксперимент, расширили тесты до сборщика мусора G1 и провели тесты на другой платформе. В этом году наши тесты были проведены со следующими сборщиками мусора:

  • -XX: + UseParallelOldGC
  • -XX: + UseConcMarkSweepGC
  • -XX: + UseG1GC

Описание окружающей среды

Эксперимент проводился на готовой конфигурации JIRA . Мотивация для тестового запуска была громкой и ясной — кроме Minecraft, Angry Bird и Eclipse на базе Dalvik, JIRA должно быть одним из самых популярных Java-приложений. И в отличие от альтернатив, он является более типичным представителем того, с чем большинство из нас имеет дело в повседневном бизнесе — в конце концов, Java все еще наиболее широко используется в серверных приложениях Java EE.

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

Мы тщательно распаковали нашу свежую загрузку JIRA 6.1 и установили ее на Mac OS X Mavericks. И запустил в комплекте тесты, ничего не меняя в настройках памяти по умолчанию. Команда Atlassian была достаточно любезна, чтобы установить их для нас:

-Xms256m -Xmx768m -XX:MaxPermSize=256m

В тестах использовались функциональные возможности JIRA различными способами: для создания задач, назначения задач, решения задач, поиска и обнаружения задач и т. Д. Общее время выполнения теста составило 30 минут.

Мы запустили тест, используя три разных алгоритма сборки мусора — Parallel, CMS и G1 были использованы в нашем случае. Каждый тест начинался с новой загрузки JVM, после чего заполнялось хранилище в том же состоянии. Только после подготовки мы запустили генерацию нагрузки.

Полученные результаты

Во время каждого запуска мы собирали журналы GC с использованием -XX: + PrintGCTimeStamps -Xloggc: /tmp/gc.log -XX: + PrintGCDetails и анализировали эту статистику с помощью GCViewer.

Результаты могут быть агрегированы следующим образом. Обратите внимание, что все измерения в миллисекундах:

Параллельно CMS G1

Всего GC пауз

20 930

18 870

62 000

Макс GC пауза

721

64

50

Интерпретация и результаты

Первая остановка — Parallel GC ( -XX: + UseParallelOldGC ). Из 30 минут, которые потребовались для завершения испытаний, мы провели около 21 секунды в паузах ГХ с параллельным коллектором. И самая длинная пауза заняла 721 миллисекунду. Итак, давайте возьмем это за основу: циклы GC снизили пропускную способность на 1,1% от общего времени выполнения. И наихудшая задержка составила 721 мс .

Следующий участник: CMS ( -XX: + UseConcMarkSweepGC ). Опять же, 30 минут испытаний, из которых мы проиграли GC чуть меньше 19 секунд. По пропускной способности это примерно в том же районе, что и параллельный режим. С другой стороны, задержка была значительно улучшена — задержка в худшем случае уменьшается более чем в 10 раз! Сейчас мы ожидаем всего 64 мс как максимальное время паузы от GC .

В последнем эксперименте использовался самый новый и блестящий из доступных алгоритмов GC — G1 ( -XX: + UseG1GC ). Были проведены те же самые тесты, и по пропускной способности мы увидели, что результаты сильно пострадали. На этот раз наше приложение потратило больше минуты в ожидании завершения GC. Сравнивая это только с 1% накладных расходов с CMS, мы сейчас сталкиваемся с почти 3,5% -ным влиянием на пропускную способность . Но если вы действительно не заботитесь о пропускной способности и хотите выжать последний бит из задержки, тогда — мы улучшили примерно на 20% по сравнению с и без того хорошей CMS — при использовании G1 самая длинная пауза GC заняла всего 50 мс.

Вывод

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

Но если бы я осмелился сделать такой вывод, я бы сказал, что CMS по-прежнему остается лучшим вариантом «по умолчанию». Пропускная способность G1 все еще намного хуже, что улучшенная задержка обычно не стоит этого.

Если вам понравился контент, рассмотрите возможность подписки на нашу RSS-ленту или Twitter-поток — мы продолжаем публиковать статьи по различным темам оптимизации производительности.