你好的Android / Java开发人员,
当一个函数调用一个函数,该函数调用另一个等等,有多少电话(堆栈长度)将让我在堆栈上的流动? 是否有一个一般的经验法则?
究其原因我问是因为我现在是更有效的(设计明智)我的5名球员卡游戏
解决方案1:
for(int i=0;i<100;i++){
p1.play();
p2.play();
p3.play();
p4.play();
}
方案2:
p1.play(); //where p1.play() calls p2.play() and so on until p4 calls p1 again.
// this will go on for 100 times
我更喜欢的解决方案2,所以如果有一个碰撞,我可以看到所有的功能从P1在我在我= 100元话费= 0至P4
但随着溶液1,堆栈要短得多,但是当有一个碰撞,我会在循环的开始看到一个被调用的函数播放(),其中事故发生
你有什么建议? 我知道这是有点问题2中1,但他们都非常相关
谢谢你们
根据我的经验,在Java堆栈溢出几乎总是由于编程错误。 见典型的尺寸在这里 。
现在,你的第二个解决方案是,国际海事组织,很丑陋......几乎一个编程错误。 假设N = 100(那种)你的游戏时间,这听起来绝对错误的内存消耗(堆栈大小)用它增加。 我不喜欢这种解决办法的。
当有碰撞,我会在循环的开始看到一个被调用的函数播放(),其中事故发生
我没有看到真正的优势。 为什么不把一个try catch
块,这样在发生碰撞的情况下,你可以打印出迭代次数?
有经验的递归或嵌套函数创建一个堆栈溢出没有一般规则。 相反,它依赖于堆栈上可用的存储器,其可以根据底层的硬件和操作系统的分配而变化。
这是很难确定的函数调用方法是没有看到更多的代码,您的情况更好。 我将同前(第一)选择一边,因为它是对所发生的事情一点更加明确,并避免可能的方法和对象实例,可能不一定是依赖于彼此连接在一起。 如果你主要是由错误报告而言,你可以尝试添加日志到您的代码以使正在发生的事情,与看着堆栈跟踪的转储沿的更详细的了解。 希望这个链接可以帮助你还有: http://developer.android.com/tools/debugging/index.html
我认为西瓦龙是正确的,有电话的无固定量,这将导致溢出。 然而,你可以用一个非常简单的递归函数测试:
public void stackTest(int iteration)
{
System.out.println("Iteration: "+iteration); // or Log
stackTest(iteration+1);
}
而这样称呼它:
stackTest(1);
然后看看它会走多远。
我不认为你可以说,X函数调用的一般数量将触发堆栈内存溢出。 这取决于功能,他们的论点,他们的返回类型等,都保存在栈内存,所以不同的功能可能需要不同量的(栈)内存。
无论如何,你永远不应该依靠代码,甚至远程接近试图多少堆栈的使用要考虑到崩溃的堆栈得到。 您的代码应始终明确waaay溢出堆栈。
每种方法的框架在Java有:局部变量表和操作数栈。 这个堆栈大小是恒定的,每一种方法可能有它不同的大小。 由于JVM规范操作数堆栈大小存储在方法属性Code
中max_stack
字段:
Code_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 max_stack;
u2 max_locals;
u4 code_length;
u1 code[code_length];
u2 exception_table_length;
{ u2 start_pc;
u2 end_pc;
u2 handler_pc;
u2 catch_type;
} exception_table[exception_table_length];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
这个尺寸在编译期间计算并可以通过JVM,当你打更改StackOverflowException
。 JVM规范:
以下例外情况与Java虚拟机相关联的栈:如果在一个线程的计算需要比允许更大的Java虚拟机堆,Java虚拟机将引发StackOverflowError。 如果Java虚拟机栈可动态扩展,并且扩展尝试,但可以提供足够的内存来实现扩张,或者如果没有足够的内存可以提供给创建一个新的线程初始Java虚拟机栈,Java虚拟机抛出一个OutOfMemoryError。
总结:这取决于你的JVM多少内存允许获得。 在不同的工作站/智能手机,你可能有可用内存的值不同。 这就是为什么你不应该写代码是依赖于这样的事情。 如果你认为OutOfMemoryException
可能发生试着解决你的问题,而不是迭代递推。
这归结为递归迭代VS的原则。
递归允许你写简单的方式的算法; 更容易理解和更快地实现。 递归算法可以转换为迭代算法,这将是更有效的存储器和更多的CPU高效。
所以决定是性能VS简单/编码的努力之一。
这里有一个关于这个话题螺纹: 递归或迭代?