当前位置: 首页 > 知识库问答 >
问题:

泊坞窗内的 Java 进程消耗的内存超过了指定的 Xmx 限制

章景同
2023-03-14

我正在docker中运行一个java进程。我已经设置了xms(388m)和xmx(388m)。在应用程序启动后的某个时候,容器的内存消耗超过并达到了大部分~主机内存大小,容器被杀死。

    < li >当我使用jprofiler连接到java进程时,我看到堆小于Xmx < li >但是,容器内顶部的命令显示< code>docker stats显示的内容 < li >当我在主机上运行相同的java进程时,它的内存使用在Xmx边界内。

详细信息:

> < li>Docker版本1.12.1,内部版本号23cf638 < li >主机操作系统:Ubuntu 14.04 < li >容器映像:Ubuntu 14.04(也尝试使用Ubuntu 16.04) < li>JRE: 1.8.0_77(试过1.8.0_112,1.8.0_121也)(都是客户端JRE;我不能使用服务器JRE,因为这个应用程序需要JavaFX。我还使用monocle在无头模式下运行应用程序) < li>

Cmd:

java-server-Djava.net.preferIPv4Stack=true-Djavafx.monocle.headless=true-Dglass.platform=Monocle-Dmonocle.platform=Headless-Dprism.order=sw-Djsse.enableSNIExtension=false-XX: ExitOnOutOfMemoryError-XX: HeapDumpOnOutOfMemoryError-Xms388m-Xmx388m-XX: MetaspaceSize=32m-XX: MaxMetaspaceSize=-jarmyApp-1.0.jar

在浏览了多个论坛之后,我还尝试设置MALLOC_ARENAS_MAX=4(也尝试了使用2和1)。

在运行docker容器时,我还尝试了设置--memory和--memoryreservation。在这种情况下,容器在达到内存限制时被终止。

观察:在jvm的整个生命周期中,它使用的次数少于Xmx(388m)。然而docker stats继续增加并达到约1.2g(主机内存为2g),并在某些时候导致java进程中的OOM。所以我假设GC释放的内存不会返回容器操作系统。

任何帮助是值得赞赏的。

我错了。

  1. 即使在容器之外(当我在主机上运行时),jvm也会消耗相同数量的内存。所以这不是docker的问题
  2. 容器内外的top命令结果相同。但是分析器中显示的堆内存在边界内
  3. 该应用程序使用JavaFX webview,它会创建许多短期线程。我相信这会导致堆栈增长(不确定是否有任何方法来衡量这一点)。

共有1个答案

颜修明
2023-03-14

我建议将资源限制在码头集装箱本身。如果您使用docker compose来运行容器,那么可以通过使用-resources标记轻松完成。这样,docker容器将从系统中获取的资源量就有了限制。

 类似资料:
  • 关于Java应用程序使用的驻留内存,我有两个问题。 一些背景细节: 我用-xms2560m-xmx2560m设置了一个java应用程序。 java应用程序在容器中运行。k8s允许容器最多消耗4GB. 堆:应用程序的工作方式似乎是使用所有内存,然后释放,然后使用等等。 这张快照说明了这一点。Y列是空闲堆内存。(由应用程序通过)提取) 我还可以使用HotSpotDiagnosticMXBean来确认它

  • 我注意到Spring Boot应用程序不服从通过Xmx选项设置的内存量。例如:java-Xss64m-Xmx64m-jartest.jar 我还在控制台上打印了应用程序在启动时实际使用的内存量,并显示:最大内存:61M 当我在访问任何网页之前打开Windows进程时,它会显示-105M,那么Java怎么能说61M呢? 在访问任何网页后,它从-125M变为-135M。为什么会有这样的增长?它应该给出

  • 与这两个问题相关的是: null Java Buildpack自动为和设置sane值。通过调优参数和配置预期线程的(最大)数量,我非常确定Java进程消耗的内存应该小于我分配给云铸造应用程序的上限。 但是,我仍然会遇到Cloud Foundry“内存不足”错误(不是Java OOM错误!): 我尝试了设置。将该值设置为1或2会导致启动缓慢。在的情况下,我仍然看到了上面描述的错误,所以这不是我的问题

  • 我有一个非常简单的Web服务器类(基于JavaSE的类)。 当我使用此命令启动编译后的类以限制内存使用时:

  • 问题内容: 我需要监视应用程序产生的线程消耗的内存量。如果贪婪的线程消耗太多内存,则想法是采取纠正措施。我已提到Java线程占用多少内存?。关于该链接的建议之一是在我尝试以下工作时使用。 我在四个线程上运行了很长时间。尽管作业不会连续地累积内存,但是所返回的值会不断增加,甚至不会下降。这意味着不会返回线程使用的堆上的实际内存量。它返回自线程启动以来在堆上为线程分配的内存总量。我的平台详细信息如下:

  • 我需要监控应用程序生成的线程所消耗的内存量。如果贪婪的线程占用了太多内存,那么我们可以采取纠正措施。我提到了我的java线程需要多少内存?。关于该链接的建议之一是在ThreadMXBean中使用getThreadAllocatedBytes 我用以下作业试验了getThreadAllocatedBytes。 我在四个线程上运行了相当长的时间。虽然作业不会连续累积内存,但getThreadAlloc