Мы используем систему RT в Java. Он часто использует относительно большие кучи (100 + ГБ) и обслуживает запросы, поступающие из очереди сообщений. Каждый запрос должен быть обработан быстро (< 100 мс) для удовлетворения SLA.Управление сборкой мусора Java в режиме реального времени
У нас возникли серьезные проблемы, связанные с GC, потому что часто бывает, что GC вызывает стоп-мировую коллекцию во время запроса (200 + мс), что приводит к сбою.
Один из наших разработчиков с разумным знанием GC провел некоторое время с настройкой параметров GC и попыткой использования разных GC. Через несколько дней он придумал некоторую параметризацию, которую мы в шутку называем «развитой генетическим алгоритмом». Это снижает паузы в GC, но по-прежнему далеки от удовлетворения требований SLA.
Решение, которое я ищу, чтобы защитить некоторые критические части коды от GC, и после того, как запрос будет завершен, пусть GC сделать столько работы, сколько ему нужно, до принятия следующего запроса. Случайные паузы за пределами запросов были бы в порядке, потому что у нас есть несколько рабочих и сборщиков мусора, которые просто не будут запрашивать запросы на некоторое время.
У меня есть некоторые идеи, которые глупо, некрасиво, и, скорее всего, не работает, но мы надеемся, что они иллюстрируют проблему:
- Иногда называют
Thread.sleep()
в принимающем потоке, молясь за GC, чтобы сделать какую-то работу в Тем временем, - Invoke
System.gc()
илиRuntime.gc()
между запросами, снова безнадежно молясь за него, чтобы помочь, - Mess код полностью с Hacky узорами, как https://stackoverflow.com/a/6915221/1137187.
Последнее важное замечание, что мы стартап малобюджетный и коммерческие решения, такие как Zing® не вариант для нас, мы ищем некоммерческое решения.
Любые идеи? Мы полностью переписываем наш код на C++ (мы не знали, что GC может быть проблемой, а не решением в начале), но база кода слишком велика для этого.
Java, конечно, не первый язык, который возникает у меня, когда я слышу термин «в реальном времени», и, учитывая, что Java выбрана, потребность в гигантской куче, похоже, не сулит ничего хорошего. –
В любом случае в долговременном процессе есть только два общих подхода к проблеме GC: (1) уменьшить количество вывозимого мусора и (2) ускорить сбор мусора. Если полные GC являются дорогостоящими, но нечастыми, то одной из альтернатив может быть значительное уменьшение размера кучи. Для этого потребуются более частые GC, но каждый должен быть быстрее, потому что не может быть столько мусора для сбора. Кроме того, старайтесь избегать долгоживущих объектов, которые дороже для коллективного GC для сбора, если только они не сохраняются на протяжении всей жизни процесса. –
Кроме того, позаботьтесь о временных объектах. Это не редкость для Java-кодеров, которые больше полагаются на GC, чем нужно, создавая и отбрасывая множество объектов. Они могут даже не признать, что они это делают. Например, конкатенация строк и автобоксинг могут здесь помочь. Примитивы не имеют стоимости GC, и, как правило, API более низкого уровня производят меньше мусора. –