8-拼图游戏 java.lang.OutOfMemoryError:GC超过限制

4
当我运行我的8拼图程序时,一直出现“GC overhead limit exceeded”的提示。我尝试给JVM添加更多内存,但没有帮助。
以下是有问题的方法:
    public void search() {
    addToQueue(start, null);// add root
    while (!queue.isEmpty()) {
        currState = queue.removeFirst();


        if (goal.equals(currState)) { 
            solution = true;
            printSolution(currState);
            break;

        } else {
            a = currState.indexOf("0");

            // left
            while (a != 0 && a != 3 && a != 6) {

                String nextState = currState.substring(0, a - 1) + "0"
                        + currState.charAt(a - 1)
                        + currState.substring(a + 1);
                addToQueue(nextState, currState);
                nodes++;
                break;
            }
            // up
            while (a != 0 && a != 1 && a != 2) {

                String nextState = currState.substring(0, a - 3) + "0"
                        + currState.substring(a - 2, a)
                        + currState.charAt(a - 3)
                        + currState.substring(a + 1);
                addToQueue(nextState, currState);
                nodes++;
                break;
            }
            // right
            while (a != 2 && a != 5 && a != 8) {

                String nextState = currState.substring(0, a)
                        + currState.charAt(a + 1) + "0"
                        + currState.substring(a + 2)
                        + currState.substring(a + 1);
                addToQueue(nextState, currState);
                nodes++;
                break;
            }
            // down
            while (a != 6 && a != 7 && a != 8) {

                String nextState = currState.substring(0, a)
                        + currState.substring(a + 3, a + 4)
                        + currState.substring(a + 1, a + 3) + "0"
                        + currState.substring(a + 4);
                addToQueue(nextState, currState);
                nodes++;
                break;
            }

        }

    }

}

Start 是我从 .txt 文件中读取的字符串。对于某些问题它可以正常工作,但是某些情况下会产生这个错误。

    private void addToQueue(String newState, String oldState) {
    if (!levelDepth.containsKey(newState)) {
        newValue = oldState == null ? 0 : levelDepth.get(oldState) + 1;
        unique++;
        levelDepth.put(newState, newValue);
        queue.add(newState);
        stateHistory.put(newState, oldState);

    }

}

@Taylor 它确实会长时间处理。 - pacman4565
1
我想到的一个可能性是:看起来你正在创建大量的字符串。你可能需要找到一种不同的方式来存储状态。我不知道这是否是你问题的原因,但所有这些字符串拼接/重新分配都有点可疑。 - Reinstate Monica -- notmaynard
2
前言: 我从未遇到过这种错误,所以我的回答可能并不准确。希望更有经验的人能够提供更多的帮助。无疑,这是一个有趣的问题。我很想知道它的解释。 - Reinstate Monica -- notmaynard
1
你的循环结构看起来有些奇怪,我不确定你是否需要一个队列。似乎你已经完成了处理(goal.equals(currState)),或者在所有这些while循环中添加了多个项到队列中。你的队列似乎只会不断增长,但你似乎只对队列中的第一项感兴趣。我有一种预感,你正在保留大量不必要的数据。 - Taylor
1
此外,你所有的内部 while 循环都依赖于变量 "a",但我没有看到它在这些循环中被改变过。你确定你不是陷入了无限循环吗?你调试过了吗? - Taylor
显示剩余8条评论
1个回答

2

您遇到的错误是由于GC线程占用了98%或更多的处理器时间。

最简单的方法是将您的方法分解成几个不同的方法,这样方法本地字符串就可以被收集。

其次,使用StringBuffer进行连接,字符串连接会使事情变得相当缓慢。

还有其他一些可以尝试的东西,如并发GC等,但帮助JRE优化您的方法结构是最重要的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接