Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中使用数组和递归时的StackOverflowError_Java_Arrays_Memory Management_Stack Overflow - Fatal编程技术网

Java中使用数组和递归时的StackOverflowError

Java中使用数组和递归时的StackOverflowError,java,arrays,memory-management,stack-overflow,Java,Arrays,Memory Management,Stack Overflow,MatrixCreatureContainer类中的lifeCycle方法在大约3-4k次迭代后抛出堆栈溢出错误。为什么呢?我假设这与内存分配有关,但我不知道如何解决它。我试着阅读关于java垃圾回收器的文章,但我所做的似乎没有任何帮助 公共类MatrixCreatureContainer{ 私人最终静态整数,生物数=20; 私有静态随机兰德; 公共静态void main(字符串[]args){ rand=新随机数(); 列表填充=新的ArrayList(); 对于(int i=0;i

MatrixCreatureContainer类中的lifeCycle方法在大约3-4k次迭代后抛出堆栈溢出错误。为什么呢?我假设这与内存分配有关,但我不知道如何解决它。我试着阅读关于java垃圾回收器的文章,但我所做的似乎没有任何帮助

公共类MatrixCreatureContainer{
私人最终静态整数,生物数=20;
私有静态随机兰德;
公共静态void main(字符串[]args){
rand=新随机数();
列表填充=新的ArrayList();
对于(int i=0;i<生物的数量;i++){
添加(新MatrixCreature());
}
集合。排序(总体);
生命周期(人口0.4000);
}
私有静态void生命周期(列表填充、int生成、int迭代){
if(generation==迭代次数)返回;
List newPopulation=newarraylist();
while(population.size()!=0){
MatrixCreature-mother=population.remove(rand.nextInt(population.size());
matrixcreatefather=population.remove(rand.nextInt(population.size());
添加(新MatrixCreature(母亲、父亲));
添加(新MatrixCreature(母亲、父亲));
添加(新MatrixCreature(母亲、父亲));
}
集合。排序(新人口);
newPopulation=newPopulation.subList(0,生物的数量);
生命周期(新人口、第1代、迭代);
}
} 
MatrixCreature类基本上只保存20个整数的整数数组(int[])。构造函数接受另外两个MatrixCreates,并结合给定的两个MatrixCreates的数组,变异的可能性很小。每个MatrixCreate都会获得一个分数(其中0是最好的),该分数表示数组中的数字之和与55的接近程度。它是对MatrixCreatureContainer中每一代的人口进行排序的分数,这样每一代中的20个“最佳”存活下来。
如果相关,我可以将代码发布到MatrixCreature类

提前感谢:)


-Boye

每个生命周期都从它自己的
种群开始,并为下一代创造一个新的种群(总是有3种生物在里面;这是有意的吗?)

因此,在4000次迭代之后,您就有了4000个人口列表,因为它们从未超出范围。

通过此调用:

lifeCycle(population,0, 4000);
您基本上要求的是4000帧的堆栈(至少-请参阅下文)。这并不是完全没有道理,但事实上根本没有理由让它递归。您可以轻松地将方法更改为迭代方法,甚至可以删除
generation
参数:

private static void lifeCycle(List<MatrixCreature> population, int iterations) {
    for (int generation = 0; generation < iterations; generation++) {
        // Body of previous method here
    }
}
私有静态无效生命周期(列表填充,整数迭代){
对于(int generation=0;generation
此外,您可以使用
newPopulation=newPopulation.subList(…)
继续创建视图。您可能不想这样做-这意味着每个操作都需要经过大量的堆栈帧,因为对视图的每次调用都将委托给其底层列表。。。如果这是另一种观点,它需要继续下去,等等,讨厌的。如果这些视图调用实际上在每个“层”中需要几个堆栈帧,那么在原始代码中很容易得到大约12K个调用的堆栈


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

Java不支持尾部递归优化,因此
生命周期方法中的最后一行为每次迭代创建一个新的堆栈框架


根据内存大小和局部变量的数量,您已经确定可以有大约4000个堆栈帧。解决方案:使用for循环重写方法。这只是一个小小的改变,您的方法实际上不需要递归。

您如何调用它?(在初始调用中,
generation
iterations
的值是多少?@JonSkeet我从main方法调用它,我更新了问题中的代码:)
while(population.size()!=0){
:这不应该是
while(population.size()>1){
?(其他提示:您似乎根本不需要递归)因此您从生成0开始,递归直到生成4000(因为没有其他终止条件)。可能递归4K次的算法远不是最佳的……这感觉像是对递归的滥用:)JVM堆栈大小是特定于操作系统的,在Linux32或Windows64上仅为128K: