Влияет ли сборка мусора на производительность программы такого типа? - PullRequest
12 голосов
/ 24 сентября 2011

Я создаю программу, которая будет работать на экземпляре AWS EC2 (вероятно), периодически вызываться через задание cron. Программа будет «сканировать» / «опрашивать» определенные веб-сайты, с которыми мы сотрудничаем, индексировать / агрегировать их контент и обновлять нашу базу данных. Я думаю, что java идеально подходит для языка, на котором можно программировать это приложение. Некоторые члены нашей команды инженеров обеспокоены ухудшением производительности функции сборки мусора java и предлагают использовать C ++.

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

Ответы [ 5 ]

11 голосов
/ 24 сентября 2011

Типичная проблема программистов на C ++ для GC - это задержка.То есть, когда вы запускаете программу, периодические GC прерывают мутатор и вызывают скачки задержки.Когда я работал для запуска веб-приложений на Java, у меня была пара клиентов, которые видели всплески задержек в журналах и жаловались на это - и моя задача состояла в том, чтобы настроить GC, чтобы минимизировать влияние этих всплесков.За прошедшие годы в GC произошли некоторые относительно сложные достижения в создании чудовищных Java-приложений с неизменно низкой задержкой, и я впечатлен работой инженеров в Sun (ныне Oracle), которые сделали это возможным.

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

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

Самые простые GC предлагают компромисс между большой кучей (высокая задержка, высокая пропускная способность) и маленькой кучей (меньшая задержка, меньшая пропускная способность).Требуется некоторое профилирование, чтобы сделать его правильным для конкретного приложения и рабочей нагрузки, но эти простые GC очень просты в конфигурации с большой кучей / высокой пропускной способностью / высокой задержкой.

11 голосов
/ 24 сентября 2011

Нет, ваши проблемы, скорее всего, необоснованны.

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

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

У нас есть собственный сканер (Java), который может успешно обрабатывать 2 миллиона страниц в день, включая некоторую дополнительную постобработку на страницу, на аппаратном оборудовании (2 ГБ ОЗУ), основным ограничением является пропускная способность.GC не является проблемой.

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

7 голосов
/ 24 сентября 2011

Извлечение и анализ веб-сайтов займут гораздо больше времени, чем сборщик мусора, его влияние, вероятно, будет незначительным. Более того, автоматическое управление памятью часто более эффективно при работе с большим количеством мелких объектов (например, строками), чем ручное управление памятью через new / delete. Не говоря уже о том, что память, собираемая мусором, проще в использовании.

5 голосов
/ 24 сентября 2011

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

Для того, чтобы некоторые коллеги могли получить надежные данные, показывающие, что GC работает так же, как и malloc /free с большим количеством доступной оперативной памяти, см .:

" Количественная оценка производительности сборки мусора и явного управления памятью ", МэтьюГерц и Эмери Д. Бергер, OOPSLA 2005.

В этом документе представлены эмпирические ответы на извечный вопрос: сборка мусора быстрее / медленнее / с той же скоростью, что и malloc / free?Мы вводим управление памятью oracular, подход, который позволяет нам измерять неизмененные программы Java, как если бы они использовали malloc и free.Результат: хороший GC может соответствовать производительности хорошего распределителя, но он занимает в 5 раз больше места.Однако, если физическая память ограничена, обычные сборщики мусора подвергаются снижению производительности на порядок.

Бумага: PDF Презентационные слайды: PPT , PDF

5 голосов
/ 24 сентября 2011

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

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

Например, создание новой строки в Java (в любой современной JVM) так же быстро, каквыделение стека в C ++.В отличие от этого, если вы не занимаетесь сложным пулированием строк в C ++, вы действительно будете облагать налогом свой распределитель с помощью множества небольших и быстрых выделений.

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

...