英文:
Java Docker Container having OutOfMemoryError
问题
我正在将一个Java Spring-Boot应用程序部署为Docker容器,这些服务器具有16 GB的内存。
Docker服务器版本为19.03.12,运行在Ubuntu 18.04.4 LTS上。我的Docker镜像已安装了openjdk-11作为Java运行时。入口点定义如下:
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]
我启动容器时没有对CPU和内存设置任何限制,但当堆空间达到8 GB时,应用程序总是因为OutOfMemoryError而崩溃。还有一些其他容器正在运行,但系统仍然有大约3-4 GB的空闲内存。
为什么容器内的JVM在使用内存时似乎受到了8 GB的限制,尽管它“看到”了整个16 GB?我需要做什么才能让JVM允许使用系统提供的所有内存?
英文:
I'm deploying a Java Spring-Boot application as a Docker container to servers having 16 GB of memory.
The Docker server version is 19.03.12 on a Ubuntu 18.04.4 LTS. My Docker image has openjdk-11 as the Java runtime installed. The entrypoint is defined as:
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]
I start the container without any restrictions to CPU and memory, but the application dies always with an OutOfMemoryError when the Heap space reaches 8 GB. There are running some other containers, but the system has still around 3-4 GB of free memory.
Why is the JVM inside the container somehow limited to use 8 GB of memory, although is 'sees' the entire 16 GB? What do I have to do that the JVM is allowed to consume as much memory the system provides?
答案1
得分: 3
你可以使用命令行开关来调整JVM可用的堆大小。例如,要设置最大堆为12GB,留下4GB供操作系统和其他JVM功能使用,请添加命令行参数 -Xmx 12G
。
没有办法告诉Java它可以使用任意多的内存,或者使用操作系统已安装的所有内存 - 请参考https://stackoverflow.com/questions/3358328/why-does-the-sun-jvm-have-a-fixed-upper-limit-for-memory-usage-xmx。
英文:
You can use command line switches to adjust the heap size available for the JVM. For example, to set a 12GB maximum heap which leaves 4GB for the operating system and other JVM functions, add the command line argument -Xmx 12G
.
There is no way to tell Java it can use as much memory as it wants, or as much as the operating system has installed - see https://stackoverflow.com/questions/3358328/why-does-the-sun-jvm-have-a-fixed-upper-limit-for-memory-usage-xmx
答案2
得分: 1
你假设JVM会为你的应用程序提供所有可用内存,但实际情况并非如此。事实上,内存量是有意限制的 - 精确的值取决于系统。您可以在这里了解有多少内存实际可供您的应用程序使用。
至于如何手动管理应用程序可以访问多少内存,请阅读这篇文章。它详细解释了JVM参数。
英文:
You are assuming that JVM gives your application to the entirety of available memory. It does not. In fact the amount of memory is deliberately capped - the exact value depends on the system. You can read more about determinig how much memory is actually available to your app here.
As for how to manually manage how much emory your app is able to access read this article. It has a nice explanation of JVM parameters.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论