![](/img/trans.png)
[英]Repeated timeouts with Java Future causes JVM to run out of memory
[英]JVM Out of Memory Causes
问题基于Oracle Hotspot JDK8。
当应用程序遇到java.lang.OutOfMemory: Java heap space
异常时,我想,其中有两个可能的原因。
-Xmx
指定大小,GC 系统无法挤出足够的空间。-Xmx
,但没有足够的物理 memory 供 JVM 堆增长。 假设-Xms
< -Xmx
。 我知道1
是 JVM 抛出java.lang.OutOfMemory: Java heap space
异常的原因。 2
是一个合理的原因吗?
我发现有些文章提到java.lang.OutOfMemoryError: native memory exhausted
,但都仅限于IBM网站。 此实验仅限于 IBM 实施的 JVM 还是 JVM 规范中的标准实验?
我用@Eugene 在回答中提供的代码做了一些实验。 正如@Holger 指出的那样,结果在不同的环境中有所不同。 我在 CentOS x64 和 Win7 x64 上使用 Hotspot JDK8 x64 进行了测试。 为简单起见,交换和虚拟 memory 被禁用。
我逐步增加 memory 绑定(-Xmx 和 -Xms)。
I.-Xmx <可用逻辑 memory
二。 可用逻辑 memory < -Xmx <最大物理 memory
三、 -Xmx >最大物理 memory
四、 -Xms >最大物理 memory
Java HotSpot(TM) 64 位服务器 VM 警告:信息:os::commit_memory(0x00000000e62a0000, 349569024, 0) 失败; error='无法分配内存' (errno=12)
VM 初始化期间发生错误 Could not reserved enough space for object heap
因此,相同的 JVM 在不同的操作系统中表现不同。
首先,正如您问题下的评论所解释的那样,GC 因“内存不足”而失败的原因更多。
证明点数 (2) 很容易,只需创建一些始终分配的代码:
public static void main(String[] args) {
test(1);
}
static void test(int x){
List<byte[]> list = new ArrayList<>();
while(x == 1){
byte [] b =new byte[1 * 1024 * 1024];
b[100] = 42;
list.add(b);
}
System.out.println(list.hashCode());
}
并在 RAM 少于100g
的系统上使用-Xms1g -Xmx100g
运行它。 您可以启用 GC 日志(例如,我在 java-9 标志中使用"-Xlog:heap*=debug" "-Xlog:gc*=debug"
)并查看 GC 最终尝试处理这种常量分配的难度失败。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.