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

Я использую JVM Explorer - ссылку на JVM Explorer, чтобы профилировать мое приложение Spring. У меня есть следующие вопросы.

  • Почему "Используемая память кучи" продолжает расти даже после приложения запущен и еще не получил запросов? (Изображение 1)

  • Почему даже после сбора мусора и до получения каких-либо запросов "Используемая память кучи" продолжает расти? (Изображение2)

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

    После запуска приложения - увеличить изображение enter image description here

    После нажатия кнопки "Запустить сборщик мусора". - увеличить изображение

enter image description here

После отправки некоторых запросов в приложение после завершения процедуры сбора мусора - увеличить изображение

enter image description here

Ответ 1

Почему "Используемая память кучи" продолжает расти даже после того, как приложение запущено и еще не получило запросов? (Изображение 1)

Что-то в вашей JVM создает объекты. Вам понадобится профайлер памяти, чтобы узнать, что это делает. Это может быть частью Swing, приложения yoru или другой библиотеки.

Кстати. Большинство инструментов профилирования используют JMX, который обрабатывает много мусора. например когда я запускаю FlightRecorder или VisualVM в некоторых моих приложениях, он показывает, что мониторинг JMX создает большую часть мусора.

Почему даже после сбора мусора и до получения каких-либо запросов "Используемая память кучи" продолжает расти? (Изображение2)

Все, что создавалось объектами, все еще создает объекты.

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

Классы лениво загружаются. Некоторые классы не нужны, пока вы ничего не сделаете.

Разве приложение не должно использовать предыдущие классы?

Да, но это не значит, что не потребуется больше классов.

почему он просто увеличивает почти все (куча, количество загруженных классов)? (Image3)

Ваше приложение делает больше работы.

Если вы не знаете, какую работу выполняет приложение, я предлагаю использовать профилировщик памяти, такой как VisualVM или Flight Recorder. Я использую YourKit для таких вопросов.

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

Ответ 2

Мне нравится @PeterLawrey хороший ответ, однако этого там нет:

Память в первую очередь предназначена для использования, а не для экономии. Вполне возможно, что ваше приложение просто хорошо написано: оно может работать с небольшой памятью и может воссоздать все, что ему нужно, но также может эффективно использовать тот факт, что ваша система имеет много памяти и приложение использует всю возможную память для более эффективной работы.

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

Если у вас нет таких проблем, как OutOfMemoryError, вам не обязательно беспокоиться. Вы все равно должны проявлять бдительность и проверять его дальше, но ваша описанная ситуация автоматически не означает, что что-то не так.

Это похоже на постоянное плач пользователей Windows: "Я купил больше памяти, но моя Windows использует все это" - это хорошо, когда используется память! Это то, за что мы его покупаем!