java - JVM内存不足崩溃

标签 java jvm

我在使用 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)

最佳答案

would setting -Xms and -Xmx to the same value help us here

可能不是。您的 JVM 堆空间不是问题,但需要注意的是,如果您允许的堆空间多于操作系统可以提供的空间,那么您就会遇到问题。

错误消息的关键部分是:

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

当操作系统无法将内存分配给 JVM 进程时,

malloc() 将失败。检查事项:

  1. 在您的应用运行时监控并记录总体计算机内存使用情况,包括交换空间。

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

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

关于java - JVM内存不足崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49317604/

相关文章:

java - 为什么锁定对象使用偏向模式但已经用薄锁锁定

java - 热点JVM Bytecode Interpreter是跟踪JIT吗?

java - 从 DB2 选择给出 [SQL0501] Cursor CRSR0001 not open

java - Slick2D 的热插拔渲染方法

java - Apache Commons Daemon - 无法启动服务

java - Netbeans,分布式 Jar 文件,增加堆大小

scala - 找不到模块 : com. eed3si9n#sbt-assembly;0.14.3

java - 具有特定格式和两位小数的 double

Java、Dropbox Api V2 - 尝试发出长轮询请求时出错

java - 创建一个垂直横向卷轴,在数组列表和逻辑方面遇到问题(Java)