【问题标题】:JVM insufficient memory crashJVM内存不足崩溃
【发布时间】:2018-03-16 09:50:14
【问题描述】:

我一直在使用 G1 垃圾收集器遇到 Java VM 崩溃。我们得到带有以下签名的 hs_err_pid.log 文件:

#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (malloc) failed to allocate 32744 bytes for ChunkPool::allocate
# Possible reasons:
#   The system is out of physical RAM or swap space
#   In 32 bit mode, the process size limit was hit
# Possible solutions:
#   Reduce memory load on the system
#   Increase physical memory or swap space
#   Check if swap backing store is full
#   Use 64 bit Java on a 64 bit OS
#   Decrease Java heap size (-Xmx/-Xms)
#   Decrease number of Java threads
#   Decrease Java thread stack sizes (-Xss)
#   Set larger code cache with -XX:ReservedCodeCacheSize=
# This output file may be truncated or incomplete.

我们目前正在使用 Runtime.maxMemory、freeMemory 和 totalMemory 监控内存可用性并抢占任何内存不足错误。这个想法是我们可以暂停操作并警告用户他们需要分配更多内存。但是,即使 Runtime.freeMemory 报告大量可用内存,我们也看到上述 JVM 崩溃。

作为 java 桌面应用程序,有什么方法可以避免这种情况发生,并使我们自己免受系统上的内存负载的影响。 例如,我们可以提供启动选项的任何组合,即,将 -Xms 和 -Xmx 设置为相同的值对我们有帮助吗?目前我们只设置了-Xmx。

我热衷于避免 Jvm 静默崩溃的糟糕用户体验。理想情况下,我们希望能够检测到 JVM 何时接近耗尽内存并采取适当的措施。

这里是从 hs_err_pid.log 获取的更多信息,用于一个示例崩溃。这是使用 -Xmx4g,总物理内存 12gb,可用物理内存 1.79gb。

Native memory allocation (malloc) failed to allocate 32744 bytes for ChunkPool::allocate

Heap:
 garbage-first heap   total 4194304K, used 3140260K [0x00000006c0000000, 0x00000006c0108000, 0x00000007c0000000)
  region size 1024K, 1526 young (1562624K), 26 survivors (26624K)
 Metaspace       used 78244K, capacity 95308K, committed 96328K, reserved 1122304K
  class space    used 11319K, capacity 22311K, committed 23112K, reserved 1048576K

Memory: 4k page, physical 12269248k(1790928k free), swap 37973052k(362096k free)

【问题讨论】:

  • 是否可以列出更多详细信息(总物理 RAM、操作系统、正在运行的其他主要内存消耗量大的进程,以及用于启动 JVM 的 vm 参数)
  • 反过来,我会建议您查看 StackOverflow 上的其他类似问题。有很多。stackoverflow.com/….
  • 你使用的是什么 JVM 和它的什么版本?
  • 这是JVM内存不足。如前所述,这可能是因为保留了太多堆。如果您有足够的空闲堆,请尝试缩小它。
  • 日志列出了许多要调查的事情,您应该列出您已经排除的内容以及根据哪些数据来避免冗余工作。

标签: java jvm


【解决方案1】:

将 -Xms 和 -Xmx 设置为相同的值对我们有帮助吗

这是个好主意。在最坏的情况下,它会在 JVM 启动后立即崩溃,这意味着 Xmx 大于系统中的可用内存。您还应该监控主机内存和交换使用情况,而不仅仅是 JVM 在运行时报告的内容。*内存。还要检查操作系统是否没有以某种方式限制应用程序可用的内存,例如 linux 中的overcommit 内核设置。

【讨论】:

  • 您能否指出我在使用运行时时如何监控主机内存和交换。*内存调用。这些调用会依赖于平台吗?
【解决方案2】:

将 -Xms 和 -Xmx 设置为相同的值对我们有帮助吗

可能不会。您的 JVM 堆空间不是问题,需要注意的是,如果您允许的堆空间超出操作系统所能提供的范围,那么您将遇到问题。

错误信息的关键部分是:

本机内存分配 (malloc) 未能为 ChunkPool::allocate 分配 32744 字节

malloc() 将在操作系统无法为 JVM 进程分配内存时失败。检查事项:

  1. 在您的应用运行时监控和记录整个机器内存使用情况,包括交换。

  2. 使用ulimit -m 检查是否存在管理员对用户进程大小的限制。共享服务器通常会施加限制以阻止一个用户占用所有资源。

  3. 如果在容器中运行,则上述两种情况都适用,但您还需要检查容器管理技术(例如 Kubernetes)施加的资源限制。

【讨论】:

  • 谢谢安迪。目前我们使用 java.lang.Runtime 方法监控内存使用情况。对于监控整体机器内存使用和交换,您有什么建议?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多