【问题标题】:Heap memory error in JavaJava中的堆内存错误
【发布时间】:2017-09-27 15:25:11
【问题描述】:

我正在对 Java 进行一些修改,但在其他一些语言方面有很多经验。 我有一个我知道解决方案的测试问题(并且可以很容易地用 Python 和 C++ 生成)。但是运行下面的 Java 代码会给出一个

线程“主”java.lang.OutOfMemoryError 中的异常:Java 堆空间

我想知道我是否犯了一个简单的错误,我不希望这个程序的内存占用非常大:

public static void main(String[] args) {
    ArrayList<Integer> longest_sequence = new ArrayList<>();
    ArrayList<Integer> this_sequence;
    int n = 0;

    for (int i = 1; i < 1000000; i++) {
        this_sequence = new ArrayList<Integer>();

        n = i;
        this_sequence.add(n);
        while (n != 1) {
            if (n % 2 == 0) {
                n = n / 2;
            }
            else {
                n = 3*n + 1;
            }
            this_sequence.add(n);
        }
        if (this_sequence.size() > longest_sequence.size()) {
            longest_sequence = this_sequence;
        }
    }

    System.out.println(longest_sequence.get(0));
    System.out.println(longest_sequence.size());

}

澄清一点:

在程序的每次迭代中都会创建一个新列表。它要么通过为其分配最长的序列来保留,要么被新的列表实例丢弃并覆盖。

我猜我对此的假设不正确,并且正在保留实例?列表的大小应该不是问题(最大的大约有 500 个元素)。

【问题讨论】:

  • 您可以尝试增加正在运行的程序的堆空间。它可能默认小于1G
  • 尝试使用this_sequence.clear(),并且只使用一个对列表的引用,而不是在循环中重新创建
  • 可能因为你的while循环,内存占用会很大,你怎么知道最大的有多大?
  • 您对代码所需的堆内存的估计是多少?
  • 这里的问题是整数溢出并且你的 Collat​​z 猜想代码没有像你期望的那样在 1 处终止。将int 替换为long,一切都很好。当然,这仍然是一种非常低效的测量序列长度的方法,根本不需要在内存中保存任何内容。

标签: java jvm out-of-memory heap-memory


【解决方案1】:

我认为最容易避免这种情况的是使用 -Xmx 标志添加内存

https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/jrdocs/refman/optionX.html 这是官方文档以了解更多信息

【讨论】:

    【解决方案2】:

    要更改 Eclipse 的 VM,您可以从 Windows> Preferences> Java> Installed JREs 更改 MV 的数量,从那里选择 JRE 并单击编辑,然后在 Default VM Arguments 中写入:to -Xmx1024M 或任何其他数量内存...

    嗯,这是不言自明的:你的内存已经用完了。

    您可能想尝试使用更多内存启动它,使用 -Xmx 标志,例如

    java -Xmx2048m [不管你以前写过什么] 这将使用最多 2 GB 的内存。

    有关详细信息,请参阅非标准选项列表。

    【讨论】:

    • 谢谢,为 VM 分配更多内存的过程是有意义的,但与我的问题有点正交:为什么这个程序内存不足?
    • 对于“为什么内存不足”这个问题的答案不能真的是“只是添加更多内存”。
    【解决方案3】:

    即使你增加堆空间也会失败。

    对于 n = 113383,一个操作使您通过整数限制并且 n 变为负数,这以无限循环结束。

    如果您将 Integer 更改为 Long,它会起作用。

    【讨论】:

    • 是的,在我发布这个问题几分钟后,我查看了我的旧 c++ 代码并立即意识到我遇到了整数溢出。我认为我在动态类型语言上花费了太多时间!谢谢。
    猜你喜欢
    • 2013-03-01
    • 2011-03-27
    • 1970-01-01
    • 2015-02-10
    • 2014-01-04
    • 1970-01-01
    • 1970-01-01
    • 2012-12-13
    • 2021-11-29
    相关资源
    最近更新 更多