Java VM 突然退出且没有明显原因

2024-04-09

我的 Java 程序突然退出,没有抛出任何异常,也没有正常完成,这是一个问题。

我正在写一个程序来解决欧拉计划 http://projecteuler.net's 。这就是我得到的:

private static final int INITIAL_CACHE_SIZE = 30000;
private static Map<Long, Integer> cache = new HashMap<Long, Integer>(INITIAL_CACHE_SIZE);

public void main(String... args) {
    long number = 0;
    int maxSize = 0;

    for (long i = 1; i <= TARGET; i++) {
        int size = size(i);
        if (size > maxSize) {
            maxSize = size;
            number = i;
        }
    }
}
private static int size(long i) {
    if (i == 1L) {
        return 1;
    }
    final int size = size(process(i)) + 1;
    return size;
}

private static long process(long n) {
    return n % 2 == 0 ? n/2 : 3*n + 1;
}

当使用 1 000 000 的 TARGET 时,它运行良好,并在大约 5 秒内正确完成。

我想通过添加缓存来优化,所以我将大小方法更改为:

private static int size(long i) {
    if (i == 1L) {
        return 1;
    }
    if (cache.containsKey(i)) {
        return cache.get(i);
    }
    final int size = size(process(i)) + 1;
    cache.put(i, size);
    return size;
}

现在,当我运行它时,当我到达 555144 时,它只是停止(进程退出)。每次都是相同的数字。没有异常、错误、Java VM 崩溃或任何异常抛出。

更改缓存大小似乎也没有任何效果,那么缓存如何 简介导致这个错误?

如果我强制缓存大小不仅是初始的,而且是永久的,如下所示:

    if (i < CACHE_SIZE) {
        cache.put(i, size);
    }

该错误不再出现。 编辑:当我将缓存大小设置为 2M 时,该错误再次开始出现。

任何人都可以重现这一点,甚至可以提供关于为什么会发生这种情况的建议吗?


这只是一个未打印的 OutOfMemoryError。如果我设置较高的堆大小,则程序运行良好,否则它将退出并显示未记录的 OutOfMemoryError(不过,在调试器中很容易看到)。

您可以通过传递此 JVM 参数并重新运行程序来验证这一点并获取堆转储(以及发生 OutOfMemoryError 的打印输出):

-XX:+HeapDumpOnOutOfMemoryError

这样它就会打印出这样的内容:

java.lang.OutOfMemoryError:Java堆空间
正在将堆转储到 java_pid4192.hprof ...
创建堆转储文件 [4.464 秒内 91901809 字节]

使用 -Xmx200m 增加堆大小,就不会出现问题 - 至少对于 TARGET=1000000 而言。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java VM 突然退出且没有明显原因 的相关文章

随机推荐