【发布时间】: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