Иногда, где-нибудь между один раз в 2 дня к один раз в 2 недели, мои сбои приложения в на вид случайном месте в коде с: java.lang.OutOfMemoryError: GC overhead limit exceeded
. Если я гуглю эту ошибку, я приезжаю в это ТАК вопрос и которые приводят меня к этой части документации солнца который экс-боли:
Параллельный коллектор бросит OutOfMemoryError, если слишком много времени будет проведено в сборке "мусора": если больше чем 98% общего времени будут потрачены в сборке "мусора", и меньше чем 2% "кучи" восстанавливаются, то OutOfMemoryError будет брошен. Эта функция разработана, чтобы препятствовать тому, чтобы приложения работали в течение длительного промежутка времени при делании минимальных успехов, потому что "куча" является слишком маленькой. При необходимости эта опция может быть отключена путем добавления опции-XX:-UseGCOverheadLimit к командной строке.
Который говорит мне, что мое приложение, по-видимому, тратит 98% общего времени в сборке "мусора" для восстановления только 2% "кучи".
Но 98% во сколько? 98% всех двух недель приложение работали? 98% последней миллисекунды?
Я пытаюсь определить лучший подход к фактическому решению этой проблемы вместо просто использования -XX:-UseGCOverheadLimit
но я чувствую потребность лучше понять проблему, которую я решаю.
Я пытаюсь определить лучший подход к фактическому решению этой проблемы, а не просто использовать
-XX: -UseGCOverheadLimit
, но я чувствую необходимость лучше понять проблему, которую я решаю.
Что ж, вы используете слишком много памяти - судя по звуку, это, вероятно, из-за медленной утечки памяти.
Вы можете попробовать увеличить размер кучи с помощью -Xmx
, что поможет, если это не утечка памяти, а признак того, что вашему приложению действительно требуется много кучи, и текущая настройка немного к низкому. Если это утечка памяти, это лишь отсрочит неизбежное.
Чтобы выяснить, является ли это утечкой памяти, проинструктируйте виртуальную машину создать дамп кучи в OOM с помощью переключателя -XX: + HeapDumpOnOutOfMemoryError
, а затем проанализируйте дамп кучи, чтобы увидеть, есть ли еще какие-либо объекты. добрее, чем должно быть. http://blogs.oracle.com/alanb/entry/heap_dumps_are_back_with - неплохое место для начала.
Изменить: По воле судьбы, я сам столкнулся с этой проблемой буквально через день после того, как этот вопрос был задан, в пакетном приложении. Это не было вызвано утечкой памяти, и увеличение размера кучи тоже не помогло. На самом деле я уменьшил размер кучи (с 1 ГБ до 256 МБ), чтобы сделать полные сборщики мусора быстрее (хотя и несколько чаще). YMMV, но стоит попробовать.
Правка 2: Не все проблемы решаются с помощью кучи меньшего размера ... Следующим шагом было включение сборщика мусора G1 , который, кажется, работает лучше, чем CMS.
> 98% будет измеряться за тот же период, за который было восстановлено менее 2% памяти.
Вполне возможно, что для этого нет фиксированного срока. Например, если проверка OOM будет выполняться после каждых 1 000 000 проверок объекта в реальном времени. Время, которое потребуется, будет зависеть от машины.
Скорее всего, вы не сможете «решить» свою проблему, добавив -XX: -UseGCOverheadLimit
. Наиболее вероятный результат состоит в том, что ваше приложение замедлится до обхода, использует немного больше памяти, а затем достигнет точки, когда сборщик мусора просто больше не будет восстанавливать любую память. Вместо этого исправьте утечки памяти, а затем (если все еще необходимо) увеличьте размер кучи.