Solución:
Puede configurar el uso de memoria del contenedor de la ventana acoplable usando -e JAVA_OPTS="-Xmx64M -Xms64M"
.
archivo de 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
ejecución de imagen:
docker run -d --name container-name -p 9100:9100 -e JAVA_OPTS="-Xmx512M -Xms512M" imagename:tag
Aquí configuro el uso de memoria de 512Mb. Puede configurar 1g o según sus necesidades. Después de ejecutarlo, verifique el uso de memoria. tendrá un máximo de 512 Mb.
Así es como se comporta Java en general. La JVM toma tanta memoria como usted le da, y realizará un proceso llamado Recolección de basura (¿Qué es el recolector de basura en Java?) Para liberar espacio una vez que decida que debe hacerlo.
Sin embargo, si no le dice a su JVM cuánta memoria puede usar, usará los valores predeterminados del sistema, que dependen de la memoria de su sistema y de la cantidad de núcleos que tenga. Puede verificar esto usando el siguiente comando (¿Cómo se determina el tamaño del montón de Java predeterminado):
java -XX:+PrintFlagsFinal -version | grep HeapSize
En mi máquina, esa es una memoria de pila inicial de 256MiB y un tamaño de pila máximo de 4GiB. Sin embargo, eso no significa que su aplicación lo necesite.
Una buena forma de medir su memoria es usando una herramienta de monitoreo como jvisualvm. Además, puede utilizar el actuador /health
endpoint para ver también el uso de la memoria del montón.
El uso de la memoria del montón normalmente tendrá un patrón de diente de sierra (¿Por qué un gráfico en forma de diente de sierra?), Donde la memoria se usa gradualmente y, finalmente, el recolector de basura la libera.
La memoria que queda después de una recolección de basura generalmente son objetos que no se pueden destruir porque todavía están en uso. Podrías ver esto como tu memoria de trabajo. Ahora, para configurar tu -Xmx
tendrás que ver cómo se comporta tu aplicación después de probarla:
- Configúrelo por debajo de su uso normal de memoria y su aplicación se quedará sin memoria, arrojando un
OutOfMemoryError
. - Configúrelo demasiado bajo pero por encima de su uso mínimo de memoria, y verá un gran impacto en el rendimiento, debido a que el recolector de basura tiene que liberar memoria continuamente.
- Configúrelo demasiado alto y reservará memoria que no necesitará en la mayoría de los casos, por lo que desperdiciará demasiados recursos.
En la captura de pantalla anterior, puede ver que mi aplicación reserva alrededor de 1GiB de memoria para el uso del montón, mientras que solo usa alrededor de 30MiB después de una recolección de basura. Eso significa que tiene una forma demasiado alta. -Xmx
value, por lo que podríamos cambiarlo a diferentes valores y ver cómo se comporta la aplicación.
La gente a menudo prefiere trabajar en potencias de 2 (aunque no hay limitación, como se ve en el patrón de configuración del montón de jvm). En mi caso, necesito ir con al menos 30MiB, ya que esa es la cantidad de memoria que usa mi aplicación en todo momento. Entonces eso significa que podría intentar -Xmx32m
, vea cómo funciona y ajuste si se queda sin memoria o funciona peor.