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