Сборка мусора и темы - PullRequest
       30

Сборка мусора и темы

21 голосов
/ 18 января 2010

AFAIK, когда GC делает свое дело, виртуальная машина блокирует все запущенные потоки - или, по крайней мере, при сжатии кучи. Так ли это в современных реализациях CLR и JVM (производственные версии на январь 2010 г.) ? Пожалуйста, не предоставляйте основные ссылки на GC, так как я понимаю элементарную работу.

Я предполагаю, что глобальная блокировка имеет место в том случае, когда происходит сжатие, ссылки могут быть недействительными в течение периода перемещения, и кажется, что проще всего заблокировать всю кучу (то есть косвенно, блокируя все потоки). Я могу представить более надежные механизмы, но KISS часто преобладает.

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

  1. Если это действительно так, то как такие мощные корпоративные движки, как JBOSS и Glassfish, поддерживают стабильно высокий показатель TPS? Я немного погуглил на JBOSS и ожидал найти в APACHE что-то вроде распределителя памяти, подходящего для веб-обработки.

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

Ответы [ 6 ]

16 голосов
/ 18 января 2010

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

О, да, и стоит отметить, что многие современные сборщики не имеют фазы уплотнения как таковой. Скорее они работают, копируя живые объекты в новое «пространство» и обнуляя старое «пространство», когда они сделаны.

Если я ошибаюсь, на мой вопрос ответит простое объяснение стратегии, используемой для минимизации блокирования.

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

... и имейте в виду, что найти точные, подробные, публичные описания внутренних компонентов производственных сборщиков мусора нелегко. (Хотя в случае с Hotspot GC вы можете посмотреть исходный код ...)

РЕДАКТИРОВАТЬ: в ответ на комментарий ОП ...

«Кажется, это так, как я и думал - не обойти часть« останови мир ».»

Это зависит. В случае Java 6 Concurrent Collector , есть две паузы во время маркировки корней (включая стеки), а затем маркировка / копирование других объектов происходит параллельно. Для других видов одновременного сборщика используются барьеры чтения или записи, когда сборщик работает, чтобы перехватить ситуации, когда потоки сборщика и приложения могли бы мешать друг другу. У меня сейчас нет моей копии [Джонса], но я также напоминаю, что можно сделать интервал "остановить мир" незначительным ... за счет более дорогих операций с указателями и / или не собирая все мусор.

2 голосов
/ 18 января 2010

Вы правы, что сборщик мусора должен будет приостановить все потоки приложения.Это время паузы может быть уменьшено с помощью Sun JVM с помощью параллельного коллектора, который выполняет некоторые работы без остановки приложения, но все равно должен приостанавливать потоки приложения.

См. Здесь http://java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html#par_gcа здесь http://java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html#cms для получения подробной информации о том, как Sun JVM управляет сборкой мусора в последних JVM.

Для веб-приложений я не думаю, что это проблема.Поскольку пользовательские запросы должны выполняться в течение небольшого промежутка времени <1 с, любые временные объекты, выделенные для обслуживания, не должны выходить из молодого поколения (при условии, что он имеет соответствующий размер), где они очищаются очень эффективно.Другие данные с более длинными жизненными циклами, такие как пользовательские сеансы, будут зависать дольше и могут повлиять на время, затрачиваемое на основные события GC. </p>

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

Наиболее близким к концепции распределителя памяти, специфичной для сети, в J2EE является пул объектов / экземпляров, который выполняется платформами и приложением.разъединяет.Например, в JBOSS у вас есть пулы EJB и пулы соединений с базой данных.Однако эти объекты обычно объединяются из-за высокой стоимости их создания, а не из-за затрат на сборку мусора.

1 голос
/ 17 августа 2010

AFAIK, когда GC делает свое дело, виртуальная машина блокирует все запущенные потоки - или, по крайней мере, при сжатии кучи.Так ли это в современных реализациях CLR и JVM (производственные версии по состоянию на январь 2010 г.)?

И у JVM Sun Hotspot, и у CLR от Microsoft есть одновременные GC, которые останавливают мир только для краткостиэтапы (чтобы получить самосогласованный снимок глобальных корней, из которых достижимы все живые данные), а не для полных циклов сбора.Я не уверен насчет их реализации сжатия, но это очень редкое явление.

Если это действительно так, как такие мощные корпоративные движки, как JBOSS и Glassfish, поддерживают стабильно высокую частоту TPS?

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

1 голос
/ 18 января 2010

Я полагаю, что IBM провела некоторые исследования по улучшению производительности GC в многоядерных системах, включая работу по сокращению или устранению проблемы «все останавливается».

например. увидеть: Параллельный, инкрементный и параллельный сборщик мусора для серверов (pdf)

Или гугл что-то вроде "параллельной сборки мусора ibm"

0 голосов
/ 18 января 2010

Современное состояние сборки мусора для Java по-прежнему включает в себя случайные паузы «останови мир».G1 GC, представленный в Java 6u14, выполняет большую часть своей работы одновременно, однако, когда памяти действительно мало, и ей нужно сжать кучу, он должен убедиться, что никто не мешает куче под ней.Это требует, чтобы больше ничего не было разрешено.Чтобы узнать больше о G1 GC, посмотрите презентацию от Sun .

0 голосов
/ 18 января 2010

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

...