Как убедить Java Garbage Collector работать, когда рабочий набор небольшой?
Это еще один вопрос «пожалуйста, скажите, как заставить сборщик мусора Java работать». В нашем приложении я считаю, что у нас есть веские причины для этого.
Это серверное приложение, которое обычно содержит около 5 миллионов живых объектов. Каждые 5 минут мы выполняем аналитическое задание, которое занимает ~ 60 секунд. Если полный GC запущен во время анализа, будет около 40M живых объектов. Дополнительные 35M объектов становятся мусором, когда анализ завершается. Сервер должен всегда отвечать на запросы (даже во время выполнения анализа).
Мы обнаружили, что полный сборщик мусора занимает около 1,5 секунд, если он вызывается, когда анализ не выполняется, но около 15 секунд, когда анализ выполняется. К сожалению, наша схема распределения такова, что полные GC обычно срабатывают во время анализа, даже если анализ выполняется только в 20% случаев. (Каждый третий или четвертый прогон анализа запускает полный сбор данных.)
Я добавил код, чтобы вызвать вызывающий много внимания метод System.gc () непосредственно перед началом анализа, если свободное место в старом поколении ниже определенного порога (5 ГБ). Выгода была очень существенной: мы получаем 1,5 секунды паузы вместо 15 секунд паузы, и мы освобождаем больше мусора в сделку. Однако иногда вызов System.gc () игнорируется, и через несколько минут мы получаем 15-секундную паузу, когда GC запускается автоматически.
Тогда мой вопрос: можем ли мы что-то сделать, чтобы убедить сборщика мусора работать? Мы запускаем 1.7.0_09-icedtea и используем Parallel GC. Я бы хотел (а) надежный способ принудительного принудительного сбора мусора, или (б) какой-то способ настроить сборщик так, чтобы он принимал более интеллектуальное автоматическое решение. (б) кажется трудным, поскольку мне не ясно, как коллекционер мог обнаружить, что наш рабочий набор изменяется таким драматическим образом.
Я готов прибегнуть к серьезным взломам, если это будет необходимо; это серьезная проблема для нас. (Мы могли бы рассмотреть компакторы CMS или G1 в качестве альтернативы, но я опасаюсь влияния CMS на пропускную способность, и считается, что G1 ведет себя плохо, несмотря на большие байтовые массивы, которые мы используем.)
добавление: В производстве наш опыт показывает, что System.gc ()обычно запускает полную сборку мусора; по крайней мере, в ситуациях, когда мы это называем. (Мы вызываем его только один раз каждые 10–30 минут, причем куча несколько, но не полностью заполнена мусором.) Было бы неплохо иметь возможность более надежно запускать сборку мусора, но это помогает нам большую часть времени.