在写一个算法中,由于递归调用次数过多,堆栈溢出。
堆栈的大小是系统控制的,无法改变。
如果递归调用出现问题,可以考虑采取循环的方式来解决,将需要的数据在关键的调用点保存下来使用。简单的说,就是用自己的数据保存方法来代替系统递归调用产生的堆栈数据。
溢出的意思就是越界,操作系统会给每个进程分配一个最大上限的堆栈空间,如果超过了这个内存空间大小程序就会coredump,就像你创建一个太大的数组会崩溃一样,因为这里堆溢出了。操作系统分配给一个进程的栈空间是2M,堆空间在32位机器上是4G。如果你的进程的栈空间使用超过了2M就会栈溢出,堆使用超过4G就会堆溢出。
那么递归为什么会导致栈溢出呢?相信大家知道栈的出入规则,就像一个瓶子,方法压栈运行,先进后出,递归的话那么先入的不能出栈,会存在栈空间中,这样就容易导致栈满而溢出。
每当你调用一个方法,在这个方法执行前都会将之前的内存地址(也就是调用点)入栈,等被调用的方法执行完将地址出栈,程序根据这个数据返回调用点。
若递归调用次数太多,就会只入栈不出栈,于是堆栈就被压爆了,此为栈溢出。
递归函数调用的太深,需要太多的内存,递归里用到的局部变量存储在堆栈中,堆栈的访问效率高,速度快,但空间有限,递归太多变量需要一直入栈而不出栈,导致需要的内存空间大于堆栈的空间。
视频解析:https://www.icourse163.org/learn/ZJU-93001?tid=1003013004#/learn/content?type=detail&id=1004242195&cid=1005239393&replay=true
如何利用循环代替递归以防止栈溢出
http://www.cnblogs.com/wb-DarkHorse/archive/2013/11/15/3284228.html
尾递归
http://www.cnblogs.com/JeffreyZhao/archive/2009/03/26/tail-recursion-and-continuation.html
http://www.cnblogs.com/JeffreyZhao/archive/2009/04/01/tail-recursion-explanation.html