Есть ли способ запланировать сборку полного мусора в Java?
У меня есть приложение, работающее по расписанию 24x6. В настоящее время, после работы в течение нескольких дней, полный GC выполняется автоматически - и обычно в течение насыщенной части дня, что отрицательно влияет на время ответа пользователя.
То, что я хотел бы сделать, это заставить Full GC - возможно, в полночь каждую ночь, в течение очень низкого времени использования - чтобы это не происходило в течение дня. Я пробовал System.gc(), но, похоже, это не гарантирует, когда произойдет полный GC, или даже если это произойдет. Есть ли способ сделать это?
Информация о версии:
Java (TM) SE Runtime Environment (сборка 1.6.0_11-b03)
Java HotSpot (TM) Server VM (сборка 11.0-b16, смешанный режим)
Дополнительно -
- Незначительные GC работают примерно каждые 10-15 секунд. Но они не освобождают достаточное количество ОЗУ, чтобы получить приложение через всю неделю. Когда Full GC действительно происходит, почти 50% кучи освобождается.
- Что касается вышеизложенного, вызов System.gc() не означает, что любой из следующих GCs будет иметь полную форму, необходимую для освобождения этих больших патронов памяти. Да, он включен (или не отключен, в зависимости от того, как вы читаете параметр -XX).
- Я уже играл с несколькими настройками GC CMS, что очень помогло, но не решило проблему. Первоначально он бросал OOMs два-три раза в неделю.
- Я хочу остановить бесконечные циклы:
- постоянно добавляя в кучу пространство, которое может продолжаться так долго
- постоянная настройка и тестирование настроек GC - это уже давно минус возвращение
- Я не хочу рассматривать это как машину NT и отказываться от нее в ночное время. Активные пользовательские сессии в течение всей ночи, и подпрыгивание приложения означало бы потеря данных сеанса.
Чтобы быть более конкретным, я больше ищу технику, чтобы гарантировать, что будет выполнен полный GC, а не простой метод/функция для вызова для его запуска.
На данный момент я смотрю на изменение процентного порога, используемого CMS, чтобы определить, когда требуется полный GC.
Спасибо за любую помощь.
Ответы
Ответ 1
jmap -histo:live <PID>
заставит Full GC как "побочный эффект" найти все живые объекты. Вы можете запланировать его переработку процессов JVM в нерабочее время.
Ваш JVM build 1.6.0_11-b03
довольно древний, но jmap
должен поддерживаться на всех 1.6 JVM HotSpot.
Ответ 2
Нет.
System.gc()
предлагает GC, что вы хотели бы коллекцию.
Кроме того, в течение спокойного периода, вероятно, очень мало мусора, и поэтому вызов System.gc()
не делает многого.
Во время пикового времени существует, по-видимому, больше активности и, следовательно, создается больше мусора - следовательно, потребность в коллекции.
Должно быть очевидно, что вы не можете откладывать сбор таким упрощенным способом. JVM будет собирать, когда это необходимо.
Вам нужно заглянуть в настройку своего GC - если вы остановите сборку мира, то у вас есть проблема. Это не должно происходить на современном сервере JVM.
Вы должны изучить настройку сборщика CMS - это довольно хорошая статья об основах системы GC на Java. В Java 7 есть новый G1GC, который может быть или не быть лучше.
Вы должны найти способ имитации условий нагрузки и попробовать разные параметры GC, CMS GC имеет множество параметров настройки и настройку, это несколько темное искусство...
Это несколько более интересная статья по настройке и бенчмаркингу GC.
Ответ 3
Я бы сказал "да" - запланировать процесс для вашего спокойного времени, который делает то, что, по вашему мнению, вызовет GC.
Ешьте серьезную память. Выделите грузовик объектов и используйте слабые ссылки, чтобы отслеживать их - просто сделайте что-нибудь в свое спокойное время, которое должно вызвать GC.
Удостоверьтесь, что у вас есть какая-то логика, которая обнаруживает GC и останавливает процесс.
Ответ 4
Невозможно принудительно и немедленно собрать, поскольку сборщик мусора является недетерминированным.