繁体   English   中英

JVM内存不足崩溃

[英]JVM insufficient memory crash

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

将-Xms和-Xmx设置为相同的值会在这里帮助我们

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

将-Xms和-Xmx设置为相同的值会在这里帮助我们

可能不是。 请注意,JVM堆空间不是问题,如果您允许的堆空间超出了操作系统的能力,那么您将遇到问题。

错误消息的关键部分是:

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM