Spring boot потребляет слишком много оперативной памяти
Я создал некоторые сервисы в spring boot, у меня есть 11 жирных банок, и я развертываю их в контейнерах docker, мои сомнения были в том, что каждая банка потребляла от 1 до 1,5 ГБ оперативной памяти без использования, я проверяю оперативную память, запустив:
docker stats containername
Сначала я подумал, что это контейнер java, и я пытаюсь изменить его на тот, который использует alpine, но ничего не изменилось, поэтому я думаю, что единственная проблема-это мой jar, так есть ли способ изменить ОЗУ, которое использует jar? Или такое поведение нормально, потому что каждый у Джара есть встроенный кот? Или, может быть, лучше собрать несколько банок вместе и развернуть их как войну и использовать только один кот для группы "банок"? Может ли кто-то поделиться своим опытом?,
Заранее благодарю.
3 ответов:
Вы можете задать использование памяти контейнера docker с помощью
-e JAVA_OPTS="-Xmx64M -Xms64M".Файл Docker:
FROM openjdk:8-jre-alpine VOLUME ./mysql:/var/lib/mysql ADD /build/libs/application.jar app.jar ENTRYPOINT exec java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jarЗапуск изображения:
docker run -d --name container-name -p 9100:9100 -e JAVA_OPTS="-Xmx512M -Xms512M" imagename:tagЗдесь я установил 512 Мб памяти . вы можете установить 1g или согласно вашему требованию. После запуска с помощью этого проверьте использование памяти. это будет максимум 512 МБ.
После просмотра документации по образу openjkd DockerHub кажется, что вы можете установить размер кучи по умолчанию, установив
-XX:MaxRAM=...:Ограничение оперативной памяти поддерживается контейнерами Windows Server, но в настоящее время JVM не могу его обнаружить. Чтобы предотвратить чрезмерное выделение памяти, - XX: MaxRAM=... параметр должен быть задан со значением, не превышающим предел оперативной памяти контейнера.
Из oracle docs:
Куча По Умолчанию Размер если начальный и максимальный размеры кучи не указаны в командной строке, они вычисляются на основе суммы памяти на машине.
Это то, как Java ведет себя в целом. JVM занимает столько памяти, сколько вы ему даете, и он будет выполнять процесс, называемый сборкой мусора (Что такое сборщик мусора в Java ), чтобы освободить место, как только он решит, что должен это сделать.
Однако, если вы не скажете JVM, сколько памяти он может использовать, он будет использовать системные значения по умолчанию, которые зависят от вашей системной памяти и количества ядер, которые у вас есть. Вы можете проверить это, используя следующую команду ( размер кучи Java по умолчанию определен):java -XX:+PrintFlagsFinal -version | grep HeapSizeНа моей машине это начальная память кучи 256MiB и максимальный размер кучи 4GiB. Однако это не означает, что ваше приложение нуждается в этом.
Хороший способ измерить вашу память-это использовать инструмент мониторинга, такой как jvisualvm. Кроме того, вы можете использовать конечную точку привода
/health, чтобы увидеть использование памяти кучи, а также.Ваше использование памяти кучи обычно будет иметь пилообразный шаблон (Почему пилообразный shaped graph ), где память постепенно используется и в конечном итоге освобождается сборщиком мусора.
Память, оставшаяся после сборки мусора, обычно является объектами, которые не могут быть уничтожены, потому что они все еще используются. Вы можете рассматривать это как свою рабочую память. Теперь, чтобы настроить ваш
-Xmx,вы должны увидеть, как ваше приложение ведет себя после его опробования:
- настройте его ниже вашего нормального использования памяти и вашего приложение будет выходить из памяти, бросая
OutOfMemoryError.- настройте его слишком низко, но выше вашего минимального использования памяти, и вы увидите огромный удар по производительности, из-за того, что сборщик мусора постоянно должен освобождать память.
- настройте его слишком высоко, и вы зарезервируете память, которая вам не понадобится в большинстве случаев, поэтому тратите слишком много ресурсов.
На скриншоте выше вы можете видеть, что мое приложение резервирует около 1GiB памяти для использования кучи, в то время как оно только использует около 30 Мбайт после сбора мусора. Это означает, что он имеет слишком высокое значение
-Xmx, поэтому мы могли бы изменить его на другие значения и посмотреть, как ведет себя приложение.Люди часто предпочитают работать в степенях 2 (даже если нет никаких ограничений, как показано вJVM heap seting pattern ). В моем случае, мне нужно идти по крайней мере с 30MiB, так как это объем памяти, который мое приложение использует в любое время. Это значит, что я могу попробовать
-Xmx32m, посмотреть, как он работает, и настроить, если он выходит из памяти или работает хуже.

Comments