В этом случае длинная коллекция мусора java для молодого поколения?
вчера у нас был следующий выход GC в нашем журнале сервера одного сервера приложений JBoss:
51628.286: [GC 51628.288: [ParNew: 1843200K->204800K(1843200K), 21.3196040 secs]
5177730K->3743415K(7987200K), 21.3217870 secs]
[Times: user=1.38 sys=0.33, real=21.32 secs]
Я понимаю результат следующим образом: молодое поколение размером 1843200K. Размер до поколения был 1843200K, размер после 204800K. Коллекция продолжалась 21,3 секунды.
Обычно наши коллекции молодого поколения продолжаются < 1 с. В каких обстоятельствах коллекции yg длится так долго?
Наши параметры JVM:
-server
-verbose:gc
-XX:+PrintGCTimeStamps
-XX:+PrintGCDetails
-XX:NewRatio=3
-XX:+UseConcMarkSweepGC
-XX:+UseParNewGC
-XX:+UseCMSCompactAtFullCollection
-XX:CMSInitiatingOccupancyFraction=60
-XX:MaxPermSize=256m
-Xss512k
-Xms8000m
-Xmx8000m
версия java:
java version "1.6.0_29"
Java(TM) SE Runtime Environment (build 1.6.0_29-b11)
Java HotSpot(TM) 64-Bit Server VM (build 20.4-b02, mixed mode)
Спасибо,
Марсель
Ответы
Ответ 1
У нас был сервер tomcat, у которого были сборки мусора, которые продолжались ~ 2 минуты. В конце концов, мы нашли причину, мы выделили больше памяти для JVM через -Xmx, чем у нас была физическая память в системе. Это вызывало пейджинг во время сбора мусора, который убивает его.
Кроме того, у нас было несколько виртуальных машин, которые работали на одной физической машине. Убедитесь, что вы не выделили больше памяти для всех виртуальных машин, чем у вас есть физическая память на сервере.
Для получения дополнительной информации см. Настройка системы управления памятью, раздел Настройка размера кучи (мой акцент):
Параметры командной строки: -Xms: -Xmx:
Размер кучи влияет на скорость распределения, сбор мусора частоту и время сбора мусора. Маленькая куча станет полной быстро и должен чаще собираться мусор. Он также больше фрагментации, делая размещение объектов медленнее. Большая куча вводит небольшие накладные расходы на сбор мусора. Куча, которая больше, чем доступная физическая память в системе должна быть выгружается на диск, что приводит к длительному времени доступа или даже к приложение замораживается, особенно во время сбора мусора.
Ответ 2
Вы используете параллельный сборщик мусора (-XX:+UseConcMarkSweepGC
), который запускается в отдельном потоке. Из опубликованного вами выпуска Times вы увидите, что сборщик мусора не работал долго. Я бы предположил, что вашей системе не хватило времени процессора для работы GC, поэтому для GC понадобилось 20 с, чтобы получить 1 с времени процессора. При использовании параллельного GC вы должны убедиться, что ваше приложение не потребляет все время процессора.
В противном случае может произойти другое: если параллельный сборщик не может освободить достаточную память и достигнет определенного барьера, он будет делать полный GC, который блокирует все остальные потоки и потребляет много времени. Этот Full GC имеет немного отличающийся результат (говорит Full GC
вместо GC
), поэтому, я думаю, это не ваша проблема.
Ответ 3
Я считаю, что подсчет времени настенных часов, поэтому, если другие процессы прерывают GC и работают некоторое время, тогда это будет неправильно сообщено.
В молодое поколение не должно быть ничего, что заставляет коллекцию занять много времени - стоимость GC пропорциональна количеству достижимых предметов, а ваши цифры показывают, что еще только досягаемость по-прежнему доступна.
Управление очередями и запуск финализаторов могут занимать значительное количество времени, но не должны (??) подсчитываться по отношению к этому числу.
http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html содержит советы по настройке GC.
Ответ 4
Я просто наткнулся на статью говорящую, что наличие огромных методов может вызвать длительные паузы GC (это последний раздел) Выдержка:
Когда компилятор компилируется, компиляторы генерируют и сохраняют информацию о том, где ссылки на объекты живут (это помогает GC и называется oop map). Методы, превышающие определенный размер, не будут JIT-in точка доступа.... Если метод не был JIT'ed, GC должен генерировать собственные карты OOP во время GC.... Большие методы означают большие времена абстрактной интерпретации для генерации oop-карт..... Кстати, огромный метод был чем-то вроде 2500 строк, так что это было то, что я назвал бы огромным.
(Текст выделен полужирным шрифтом)