【问题标题】:SpringBoot insufficient memory for the Java Runtime EnvironmentSpringBoot Java Runtime Environment 内存不足
【发布时间】:2021-08-18 20:32:24
【问题描述】:

我正在 5 个线程中执行超过 30000 个 REST 请求(每个线程 6000 个),以在 SpringBoot 内的 Tomcat 之上运行 Swagger,并在运行 35 分钟后出现下一个错误:

#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (mmap) failed to map 16384 bytes for committing reserved memory.
# Possible reasons:
#   The system is out of physical RAM or swap space
#   The process is running with CompressedOops enabled, and the Java Heap may be blocking the growth of the native heap
# Possible solutions:
#   Reduce memory load on the system
#   Increase physical memory or swap space
#   Check if swap backing store is full
#   Decrease Java heap size (-Xmx/-Xms)
#   Decrease number of Java threads
#   Decrease Java thread stack sizes (-Xss)
#   Set larger code cache with -XX:ReservedCodeCacheSize=
#   JVM is running with Zero Based Compressed Oops mode in which the Java heap is
#     placed in the first 32GB address space. The Java Heap base address is the
#     maximum limit for the native heap growth. Please use -XX:HeapBaseMinAddress
#     to set the Java Heap base and to place the Java Heap above 32GB virtual address.
# This output file may be truncated or incomplete.
#
#  Out of Memory Error (os_linux.cpp:2985), pid=24780, tid=58785
#
# JRE version: OpenJDK Runtime Environment (11.0.11+9) (build 11.0.11+9-Ubuntu-0ubuntu2.20.04)
# Java VM: OpenJDK 64-Bit Server VM (11.0.11+9-Ubuntu-0ubuntu2.20.04, mixed mode, sharing, tiered, compressed oops, g1 gc, linux-amd64)

Command Line: -Xverify:none -XX:TieredStopAtLevel=1 -Xms2g -Xmx10g com.CamelSpringBootApplication

Host: Common KVM processor, 16 cores, 28G, Ubuntu 20.04.2 LTS
Time: Mon May 31 15:40:22 2021 CEST elapsed time: 2122.252495 seconds (0d 0h 35m 22s)

SpringBoot 应用程序正在 Ubuntu VM 上运行,该 VM 应该有 64GB 的 RAM,但正如您在下一张图中看到的那样,价值正在疯狂下降。

我遗漏了一些信息,不知道这是什么原因。我在哪里犯错?究竟是什么占用了这么多内存,如何在运行时释放内存?

只有在重新启动 VM 后,内存才会恢复到 64GB。 在我再次启动 SpringBoot 应用程序后,RAM 甚至在运行 REST 请求之前就开始下降。 我需要支持尽可能多的 REST 请求,保留 RAM 并阻止 SpringBoot 应用程序崩溃。

更新:

这些是收集的堆转储的结果。我已将 heapdump.bin 加载到 heaphero.io 中。我将不胜感激任何基于此结果的提示。

【问题讨论】:

  • 您可以查看应用程序崩溃时生成的堆转储(或在高内存消耗期间手动创建一个)。您可以使用它来查看需要大量内存的内容。
  • 我可以使用哪些工具来做到这一点?有什么我可以直接在虚拟机内的终端中运行的吗?
  • 请参阅this,了解如何获取堆转储。然后,您可以使用 eclipse 内存分析器工具等工具对其进行分析。
  • 我已使用堆转储统计信息更新了问题。使用后我会尝试清理字符串。
  • 我没能找到这种内存行为的确切原因,但很可能主要原因是我的代码应该被编辑和优化。内存泄漏的另一个可能原因是 Spring Boot 中的 Tomcat 需要在短时间内处理大量请求(如果不自动完成,则应正确关闭),并应为该任务正确配置。

标签: java spring-boot memory-leaks


【解决方案1】:

只是一个危险的猜测,你可能会超过垃圾收集 数完那 30000 左右的四分之一后,调用 System.gc(); 通知收集垃圾。 This i wrote 位于 RAM 中,需要一个小的垃圾管理检查和计数器。

【讨论】:

  • 我在代码中添加了很多 System.gc() 调用,并在它们之前将变量(主要是 ArrayLists、Maps 和 JSONObjects)设置为 null,但看起来 Java 忽略了这些调用内存还在下降。
【解决方案2】:

我希望您已经分配了足够的堆大小,即使您的 Linux 机器有 64 GB RAM,您也需要根据应用程序传入的流量从外部扩展其默认容量。

您可以在 pom.xml 文件中增加 Spring Boot 应用程序的堆大小,如下所示 -

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <jvmArguments>-Xmx4096m</jvmArguments>
    </configuration>
</plugin>

【讨论】:

  • 我已将 -Xmx 扩展至 16 GB,但没有帮助。
猜你喜欢
  • 2015-11-30
  • 1970-01-01
  • 2019-02-19
  • 1970-01-01
  • 2021-03-29
  • 1970-01-01
  • 2013-10-23
  • 2012-06-21
  • 2013-09-10
相关资源
最近更新 更多