У меня есть веб-приложение Java, работающее на Tomcat 7, которое, похоже, имеет утечку памяти. Среднее использование памяти приложения увеличивается линейно с течением времени при загрузке (определяется с помощью JConsole). После того, как использование памяти достигнет плато, производительность значительно ухудшается. Время отклика составляет от ~ 100 мс до [300 мс, 2500 мс], поэтому это фактически вызывает реальные проблемы.
Профиль памяти JConsole для моего приложения:
Используя VisualVM, я вижу, что по меньшей мере половина памяти используется массивами символов (т.е. char []) и что большинство (примерно одинаковое количество каждого, 300 000 экземпляров) строк являются одним из следующих: "Ошибка распределения", "Копировать", "конец младшего GC", все из которых, похоже, связаны с уведомлением о сборе мусора. Насколько я знаю, приложение вообще не отслеживает сборщик мусора. VisualVM не может найти корень GC для любой из этих строк, поэтому мне трудно отслеживать это.
Сброс кучи памяти Analyzer:
Я не могу объяснить, почему пласты использования памяти такие, но у меня есть теория о том, почему производительность ухудшается, как только это происходит. Если память фрагментирована, приложение может занимать много времени, чтобы выделить непрерывный блок памяти для обработки новых запросов.
Сравнивая это со встроенным приложением статуса сервера Tomcat, память увеличивается и выравнивается, но не попадает в высокий "пол", как мое приложение. Он также не имеет большого количества недостижимых char [].
Профиль памяти JConsole приложения статуса сервера Tomcat:
Память анализатора памяти кучи состояния сервера Tomcat applicationp:
Где могут быть выделены эти строки и почему они не собираются мусором? Существуют ли параметры Tomcat или Java, которые могут повлиять на это? Существуют ли определенные пакеты, которые могут повлиять на это?