GAE использует гораздо больше памяти, чем мое Java-приложение

#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 МБ.