【发布时间】: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内存不足。如前所述,这可能是因为保留了太多堆。如果您有足够的空闲堆,请尝试缩小它。
-
日志列出了许多要调查的事情,您应该列出您已经排除的内容以及根据哪些数据来避免冗余工作。