Лучшая практика для обработки утечек памяти в крупных проектах Java?

Почти во всех крупных проектах Java, с которыми я связан, я заметил, что качество обслуживания приложения ухудшается с временем работы контейнера. Это, скорее всего, связано с утечками памяти в коде.

Правильный способ решить эту проблему - это, очевидно, отследить основную причину проблемы и устранить утечки в коде. Быстрый и грязный способ решения проблемы - просто перезапустить Tomcat (или любой контейнер сервлетов, который вы используете).

Это мои три вопроса:

  • Предположим, что вы решили решить проблему, проверив основную причину проблемы (утечка памяти), как бы вы собирали данные для увеличения проблемы?

  • Предположим, что вы выбрали быстрый и грязный способ ускорить процесс, просто перезапустив контейнер, как бы вы собирали данные для выбора оптимального цикла перезапуска?

  • Вы могли развертывать и запускать проекты в течение длительного периода времени, не перезапуская контейнер сервлета, чтобы восстановить привязанность? Или иногда сервлет перезапускает то, что нужно просто принять?

Ответ 1

Предположим, что вы решили решить проблему, проследив основную причину проблемы (утечки памяти), как бы вы собирали данные для увеличения проблемы?

Возьмите кучу кучи, используя jmap и загрузите дамп, используя Eclipse Memory Analyzer. Оттуда вы можете проанализировать, какие объекты потребляют большую часть памяти, которые "корни" предотвращают сбор других объектов и т.д.

Существуют другие программы анализа кучи, такие как jhat, но я нашел, что EMA является самым быстрым и лучшим (бесплатно).

Предположим, что вы выбрали быстрый и грязный способ ускорить процесс, просто перезапустив контейнер, как бы вы собирали данные для выбора оптимального цикла перезапуска?

Используйте JMX для контроля размера кучи и других статистических данных о куче и GC.

Вы могли развертывать и запускать проекты в течение длительного периода времени, не перезапуская контейнер сервлета, чтобы восстановить привязанность?

Да. Избегая/устраняя утечки памяти.

Ответ 3

Есть отличные инструменты для профилирования. Научитесь регулярно использовать его и понимайте вывод выделения памяти.

В основном вы выполняете этот процесс для каждой важной функции вашего приложения:

  • Запустите процесс один раз
  • GC дважды
  • Отметьте текущие подсчеты распределения для всех объектов
  • снова запустите ваш процесс.
  • GC дважды
  • Еще раз отметить
  • Разделите две метки

Если они не очень близки, у вас, вероятно, есть утечка.

Если какой-либо счет объекта растет на заданную величину на каждой итерации этого процесса, тогда у вас есть полная утечка.

Ответ 4

В идеале вам не нужно перезапускать программу или сервлет.

Мой опыт в том, что большинство причин проблем с памятью обычно возникают из-за проблемы при распределении или объединении небольшого набора классов.

Инструмент, подобный VisualVM, отлично подходит для этого, так как вы можете определить, где находится основная нагрузка вашего размещения объекта.

Это, вероятно, немного сложнее с tomcat, так как вы также будете контролировать структуру, но с достаточной тщательностью и терпением вы часто можете определить горячие точки в своей логике.