2010-01-18 3 views
21

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

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

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

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

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

ответ

16

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

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

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

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

.

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

EDIT: в ответ на комментарий OP ...

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

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

+0

(+1) обязательно купит эту книгу. То, что я хотел бы узнать больше, это то, что происходит после «копирования на новую и процедуру обновления»? предположительно все ссылки обновляются, блокируя все потоки? Или это итерационная процедура? –

+2

Насколько я знаю, даже самые совпадающие сборщики мусора «останавливают мир» для некоторых своих работ, хотя большинство задач выполняются одновременно. Однако CMS-коллектор в JVM 6 использует все доступные процессоры во время фазы останова. –

+0

@edgar Спасибо, «CMS-collector» полезный термин для поиска - я просмотрю детали, когда у меня будет время. Кажется, это так, как я думал, - не обойти стороной «остановить мир». Было бы интересно иметь некоторую гипотезу или некоторые номера ярлыков о том, как эти глобальные фазы блокировки влияют на скорости TPS серьезных серверов производства (например, те, которые я упоминал в вопросе). –

0

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

+0

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

+0

a.k.a. (в основном) Параллельная развертка Mark. Значительно (в основном). –

+0

Имеются полностью параллельные GC для других JVM. –

2

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

См. Здесь 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 для получения подробной информации о том, как солнце JVM управляет сборкой мусора в новейших JVM.

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

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

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

+0

(+1) Хорошее обсуждение - я перегоняю, что мне нужно посмотреть на коллектив коллектора «minor cycle», чтобы посмотреть, что это за эффекты. Предполагается, что характеристики TPS веб-сервера сильно зависят от распределений запросов, оставшихся в качестве объектов молодого поколения. –

+0

@ Hassan Да, параграф о молодом поколении является предположением и будет зависеть от вашего приложения, хотя вы можете настроить размер поколений в JVM. Дело в том, что вы не должны слишком беспокоиться о временных объектах, созданных во время обработки запроса, поскольку текущие коллекторы сборщиков мусора очень хороши в их очистке. Запуск нескольких JVM может помочь с более долговечными объектами, такими как пользовательские сеансы, поскольку они могут быть распределены между JVM, что означает, что для каждой JVM требуется меньше проверки во время основной коллекции. – Aaron

+0

-1: GC не нужно останавливать все потоки (иначе «остановить мир»). –

0

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

+0

-1: Современная сборка мусора для Java полностью совладает уже много лет. Есть * жесткие * JVM в реальном времени там ... –

1

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

E.g. см: A Parallel, Incremental and Concurrent GC for Servers(pdf)

Или Google что-то вроде «параллельного сбора мусора IBM»

1

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

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

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

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

Смежные вопросы