Излишнее продвижение объектов Java в старое поколение сразу после незначительного gc, вызывающего проблемы фрагментации памяти

Мы столкнулись со странной проблемой утечки памяти в нашем приложении.

Конфигурация ГХ: ParNew + CMS

Определенный тип объектов слишком рано переводится в старое поколение и вызывает серьезные проблемы с фрагментацией.

  1. У выжившего было достаточно места для размещения этих предметов.
  2. Порог выдержки составляет 15 циклов, на основании чего преждевременного продвижения по службе не произошло.

Об этих объектах: это прокси-объекты, созданные с использованием вспомогательной библиотеки Java.

Из-за ненужного продвижения таких объектов Старое поколение слишком быстро загрязняется и происходит сильная фрагментация.

Наши наблюдения:

  1. Объект выделяется только в eden. Нет проблем, связанных с размером.
  2. Объем объекта очень мал, и он подходит для сборки мусора в следующем второстепенном gc.
  3. Чтобы гарантировать это, мы напечатали несколько логгеров в finalize() и заметили, что область действия заканчивается сразу после запроса. Сразу после первого второстепенного сборщика мусора.

Примечание: finalize() добавлен только для отслеживания. Даже без finalize() продвижение старого поколения происходит.

  1. После единственного второстепенного gc:
  • ожидается, что объект будет очищен.
  • Но объект продвигается к старому поколению. С помощью множественных дампов кучи мы можем отследить продвижение объекта до старого поколения.
  1. Все такие объекты накапливаются в старом поколении и собираются сборщиком мусора старого поколения.
  2. Такое поведение наблюдается только на производственных серверах и не воспроизводится в тестовых средах.

Пожалуйста, предложите, как действовать дальше, и исправить это.

0 ответов

Другие вопросы по тегам