Является ли сборщик мусора (.net/java) проблемой для систем реального времени?

При построении системы, которая должна реагировать очень последовательно и быстро, является ли сборщик мусора потенциальной проблемой?

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

Прошло еще несколько лет, но мне интересно, если это все еще проблема. Я читал о новом сборщике мусора в.Net 4, но он все еще выглядит как большой черный ящик, и вы просто должны верить, что все будет хорошо.

Если у вас есть система, которая всегда должна быстро реагировать, проблема с сборщиком мусора слишком большая, и лучше ли выбирать более жесткий, контролируйте ее на собственном языке, таком как C++? Мне бы очень не хотелось, чтобы, если это оказалось проблемой, вы практически ничего не могли с этим поделать, кроме как ждать новой версии среды выполнения или делать очень странные вещи, чтобы попытаться повлиять на сборщика.

РЕДАКТИРОВАТЬ

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

7 ответов

Решение

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

Более подробную информацию можно найти в Спецификации реального времени для Java об одном из подходов к достижению поведения в реальном времени с использованием Java. Идея RTSJ очень проста - не использовать кучу. RTSJ предоставляет новые разновидности объектов Runnable, которые гарантируют, что потоки не получат доступ к памяти кучи любого вида. Потоки могут получать доступ к памяти в области (ничего необычного здесь; значения закрываются при закрытой области действия) или к бессмертной памяти (которая существует в течение всего времени жизни приложения). Переменные в бессмертной памяти перезаписываются снова и снова с новыми значениями.

Используя бессмертную память, RTSJ гарантирует, что потоки не обращаются к куче, и, что более важно, система не имеет сборщика мусора, который препятствует выполнению программы потоками.

Более подробная информация доступна в документе "Проект Золотые Ворота: на пути к Java в реальном времени в космических полетах", опубликованном JPL и Sun.

Я писал игры на Java и.NET и никогда не считал это большой проблемой. Я ожидаю, что ваши "ужасные истории" основаны на сборщиках мусора много лет назад - с тех пор технология действительно продвинулась далеко.

Единственное, что я не хотел бы использовать Java/.NET для сбора мусора, это что-то вроде встроенного программирования с жесткими ограничениями в реальном времени (например, контроллеры движения).

Тем не менее, вам необходимо знать о паузах ГХ, и все перечисленное может быть полезным для минимизации риска пауз ГХ:

  • Минимизируйте распределение новых объектов - хотя распределение объектов в современных системах GC чрезвычайно быстро, они вносят вклад в будущие паузы, поэтому их следует минимизировать. Вы можете использовать такие методы, как предварительное выделение массивов объектов, хранение пулов объектов или использование неупакованных примитивов.
  • Используйте специализированные библиотеки с низкой задержкой, такие как Javalution, для интенсивно используемых функций и типов данных. Они разработаны специально для приложений реального времени / с малой задержкой
  • Убедитесь, что вы используете лучший алгоритм GC, когда доступно несколько версий. Я слышал хорошие отзывы о Sun G1 Collector для приложений с низкой задержкой. Лучшие системы GC выполняют большую часть своих сборок одновременно, так что сборкам мусора не нужно "останавливать мир" очень долго, если вообще.
  • Настройте параметры GC соответствующим образом. Обычно существует компромисс между общей производительностью и временем паузы, вы можете улучшить последнее за счет первого.

Если вы очень богаты, вы, конечно, можете купить машины с аппаратной поддержкой GC.:-)

Да, мусор должен обрабатываться детерминистическим образом в системах реального времени.

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

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

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

С теоретической точки зрения сборщики мусора - это не проблема, а решение. Системы реального времени сложны, когда есть динамическое распределение памяти. В частности, обычные функции C malloc() а также free() не предоставляют гарантии в реальном времени (они обычно бывают быстрыми, но имеют, по крайней мере теоретически, "наихудшие случаи", когда они используют непомерное количество времени).

Бывает, что возможно построить динамический распределитель памяти, который предлагает гарантии в реальном времени, но для этого требуется, чтобы распределитель выполнял некоторые тяжелые действия, в частности, перемещал некоторые объекты в ОЗУ. Перемещение объектов подразумевает корректировку указателей (прозрачно, с точки зрения кода приложения), и в этот момент распределитель находится всего в одном небольшом шаге от сборщика мусора.

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

Также обратите внимание, что обычные реализации Java или.NET выполняются в операционных системах, которые также не работают в режиме реального времени (ОС может принять решение о планировании других потоков или может агрессивно отправлять некоторые данные в файл подкачки и т. Д.), И ни одна из них не является базовое оборудование (например, типичный жесткий диск может время от времени делать "паузы перекалибровки"). Если вы готовы терпеть случайный сбой синхронизации из-за аппаратного обеспечения, то у вас должно быть все в порядке с (тщательно настроенным) сборщиком мусора JVM. Даже для игр.

Это потенциальная проблема, НО...

Ваш персонаж может также зависнуть в середине вашей программы на C++, в то время как ОС извлекает страницу памяти с перегруженного жесткого диска. Если вы не используете ОС реального времени на оборудовании, разработанном для обеспечения конкретных гарантий производительности, вам никогда не гарантируется производительность.

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

Вы держите пари, что это проблема. Если вы пишете приложения с низкой задержкой, вы не можете позволить себе сделать паузу в остановке мира, которую навязывает большинство сборщиков мусора. Поскольку Java не позволяет вам отключать GC, единственный вариант - не создавать мусор. Это можно сделать и было сделано с помощью пула объектов и начальной загрузки. Я написал статью в блоге, где подробно об этом говорю.

Наша компания использует большое программное обеспечение на основе.Net, которое, помимо прочего, контролирует двоичные датчики в сетях полевой шины. В некоторых ситуациях датчики активируются только на короткий промежуток времени (300 мс), но нашему программному обеспечению все еще необходимо фиксировать эти события, так как контролируемая система немедленно выйдет из строя, если событие пропущено. Недавно мы наблюдали увеличение проблем на сайтах наших клиентов из-за сборщика мусора, работающего в течение длительного времени (до 1 секунды). Мы все еще пытаемся выяснить, как установить ограничение по времени для сборщика мусора. В заключение этого короткого рассказа я бы сказал, что сборщик мусора является недостатком в критических по времени приложениях.

Другие вопросы по тегам