#java #spring-boot #google-app-engine #google-cloud-platform
#java #весенняя загрузка #google-app-engine #google-облачная платформа
Вопрос:
У меня есть Java-приложение (Spring Boot), работающее на Google App Engine; однако я вижу странные различия между потреблением памяти моего Java-приложения и панелью мониторинга, показанной GAE.
На моем локальном компьютере, использующем VisualVM, я вижу, что он не потребляет более 100 МБ даже в пиковые периоды, и я добавил сервлет для возврата объема используемой памяти:
@GetMapping("/")
public String index() {
Runtime rt = Runtime.getRuntime();
long total = rt.totalMemory();
long free = rt.freeMemory();
long used = total - free;
return "Total: " total / 1024 / 1024 "MB<br>Used: " used / 1024 / 1024 "MB<br>Free: " free / 1024 / 1024 "MB";
}
мое развернутое приложение в GAE прямо сейчас возвращает:
Total: 91MB
Used: 69MB
Free: 21MB
в то же время панель инструментов GAE показывает, что она потребляет около 350 МБ ПАМЯТИ.
Почему это произошло? Это заставляет меня использовать экземпляр F2; если я понизлю рейтинг до F1, он продолжит сбой и перезапуск.
Я заметил, что как только я изменил свой cronjob с каждых 30 минут на запуск каждые 2 минуты, они начали взимать с меня плату за 40 часов в день в инстансах внешнего интерфейса, это было примерно за 16 часов до этого изменения, и у меня запущен только 1 инстанс. Как это возможно? количество экземпляров img url
Спасибо
Комментарии:
1. Каковы параметры JVM в двух средах?
2. @tgdavies в моем файле app.yml: среда выполнения: java11 точка входа: java -Xms64M -Xmx256M -XX: UseG1GC -XX: ParallelRefProcEnabled -XX: PrintCommandLineFlags -jar myjar.jar . На моем локальном компьютере я не устанавливаю никаких параметров JVM, работающих в моей среде разработки Eclipse.
3. Во-первых, total — free не является точной мерой того, сколько памяти использует JVM с точки зрения операционной системы, о чем, вероятно, сообщает GAE. Свободная память кучи по-прежнему выделяется для JVM и недоступна для других приложений. Вы должны посмотреть на общую память, которую использует ваш локальный процесс JVM.
4. @tgdavies существует огромная разница между неточной (~ 20% или около того) и разницей в 500% — это именно та разница, которую я получаю в совершенно другом случае использования. я предполагаю, что это общая проблема в Google…
Ответ №1:
Причина, по которой вы видите эти различия, связана с тем, что облачная консоль отображает фактический размер процесса JVM (который включает в себя кадры стека, постоянное пространство поколений, прямые буферы, машинный код и т. Д.), Где ограничение памяти, которое применяется для экземпляров, относится к куче JVM. Среда выполнения использует некоторую память кучи, которая учитывается при общем использовании кучи приложением.
Теперь важно понять, что делают эти методы и как рассчитать доступную память для выделения:
totalMemory ():
Вся память, используемая в настоящее время JVM. Обычно это меньше, чем maxMemory, потому что JVM лениво выделяет память, «лениво» означает, что часть памяти выделяется изначально и используется, и, если требуется новый фрагмент памяти, выполняется другое выделение, вплоть до всей доступной памяти (
maxMemory()
) .
maxMemory ():
Максимальная доступная память кучи (размер экземпляра ограничен этим значением).
freeMemory ():
Часть памяти в настоящее время как выделена JVM, так и не используется.
«Реальная общая память», которая может быть выделена, это:
rt.freeMemory() (rt.maxMemory() - rt.totalMemory())
Таким образом, может быть доступно больше памяти, чем вывод rt.freeMemory()
.
Комментарии:
1. у меня та же проблема с «total», возвращающим 24 МБ, но моя панель управления утверждает, что JVM использует> 128 МБ, и хотя я могу принять «секретное использование встроенной памяти» в качестве объяснения некоторых различий, это не объясняет фактор 5 для тестового примера, который просто регистрирует простое сообщение при каждом запросе. ничто не оправдывает использование 128 МБ.