java - Java 使用数组和递归时出现 StackOverflowError

标签 java arrays memory-management stack-overflow

我的 MatrixCreatureContainer 类中的 lifeCycle 方法在大约 3-4k 次迭代后抛出堆栈溢出错误。这是为什么?我认为这与内存分配有关,但我不知道如何解决它。我尝试阅读有关 java 垃圾收集器的内容,但我所做的一切似乎都没有帮助。

public class MatrixCreatureContainer {

    private final static int NUMBER_OF_CREATURES = 20;
    private static Random rand;

    public static void main(String[] args){

        rand = new Random();
        List<MatrixCreature> population = new ArrayList<MatrixCreature>();

        for(int i = 0; i < NUMBER_OF_CREATURES ; i++){
            population.add(new MatrixCreature());
        }

        Collections.sort(population);

        lifeCycle(population,0, 4000);
    }

    private static void lifeCycle(List<MatrixCreature> population, int generation, int iterations){

        if (generation == iterations) return;

        List<MatrixCreature> newPopulation = new ArrayList<MatrixCreature>();

        while(population.size() != 0){
            MatrixCreature mother = population.remove(rand.nextInt(population.size()));
            MatrixCreature father = population.remove(rand.nextInt(population.size()));
            newPopulation.add(new MatrixCreature(mother,father));
            newPopulation.add(new MatrixCreature(mother,father));
            newPopulation.add(new MatrixCreature(mother,father));
        }

        Collections.sort(newPopulation);

        newPopulation = newPopulation.subList(0,NUMBER_OF_CREATURES);

        lifeCycle(newPopulation,generation + 1, iterations);

    }

} 

MatrixCreature 类基本上只保存一个包含 20 个整数的整数数组 (int[])。构造函数接受另外两个matrixCreatures,并组合给定的两个matrixCreatures 的数组,并且有很小的变异机会。每个matrixCreature都会获得一个分数(其中0是最好的),表示数组中的数字总和与55的接近程度。该分数对MatrixCreatureContainer中每代的种群进行排序,以便每代中的20个“最佳”生存下来。
如果相关,我可以将代码发布到 MatrixCreature 类。

提前致谢:)

-博野

最佳答案

通过此调用:

lifeCycle(population,0, 4000);

你基本上要求一个具有 4000 帧的堆栈(至少 - 见下文)。这并不是完全不合理,但事实上根本没有理由进行递归。您可以轻松地将方法更改为迭代 - 甚至删除生成参数:

private static void lifeCycle(List<MatrixCreature> population, int iterations) {
    for (int generation = 0; generation < iterations; generation++) {
        // Body of previous method here
    }
}

此外,您可以继续使用 newPopulation = newPopulation.subList(...) 创建 View 。您可能不想这样做 - 这意味着每个操作都需要经历大量的堆栈帧,因为对 View 的每次调用都将委托(delegate)给其底层列表......如果这是另一个 View ,它需要继续进行,等等。令人讨厌。如果这些 View 调用实际上需要每个“层”几个堆栈帧,那么您的原始代码中很容易会得到大约 12K 调用的堆栈......

我建议在每次迭代时创建列表相关部分的副本 - 然后返回最终列表。

关于java - Java 使用数组和递归时出现 StackOverflowError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23995856/

相关文章:

java - 更改 JMenuBar 的字体

c++ - 异常安全构造函数

c++ - C++中的delete和调用析构函数有什么区别

java - Windows Firefox 和 MAC chrome 最大化命令不起作用

java - 在发送邮件中添加另一个电子邮件地址

windows-7 - 在 Windows 7 中使用 java jre6 而不是 jre7

java - 如何将两个 long 转换为字节数组 = 如何将 UUID 转换为字节数组?

javascript - PHP 中的分块数组为 3(在 JS 中可以解决)

c# - System.Array 到列表的转换

ios - 重用 View Controller 及其 ivars、scrollviews、tableview