python-栈溢出(stack overflow)问题解决方案

栈溢出(stack overflow)问题解决方案

场景
eg:

Fatal Python error: Cannot recover from stack overflow
原因: 使用递归函数调用过多导致栈溢出。
Python中,函数调用,通过栈(stack)实现;
当进入函数调用,相当于一次push压栈操作,每当函数返回,相当于一次pop出站操作。由于栈的大小不是无限的,所以递归调用次数过多,会导致栈的溢出。

Windows程序的内存机制大概是:
全局变量(局部的静态变量本质也属于此范围)存储于堆内存, 该段内存较大, 一般不会溢出;函数地址、参数、局部变量等信息存储于栈内存,栈内存较小容易发生溢出现象,但是效率较高。

总结

  1. 函数递归调用层次过深,每次调用一次, 函数参数、局部变量等信息就压栈一次,并且没有及时出站;
  2. 局部变量体积太大;

解决方法

1、递归调用改用while 或者for 循环实现(推荐使用);
2、通过尾递归 + 生成器的方法;
3、改用堆内存, 函数定义很大的局部变量(eg: 大数组),此时局部变量可以改变为静态变量(或者全局变量);
4、增大栈的大小值。

尾递归+生成器
eg:

import types
 
def f_recursive(cur_i, cur_computer_result=1):
    if cur_i == 1:
        yield cur_computer_result
 
    yield f_recursive(cur_i - 1, cur_i + cur_computer_result)
 
def f_recursive_wapper(generator, i):
    gen = generator(i)
    while isinstance(gen, types.GeneratorType):
        gen = gen.__next__()
 
    return gen
 
print(f_recursive_wapper(f_recursive,10000))

修改栈的大小

import sys
sys.setrecursionlimit(2000)
def f(i):
    if i == 1:
        return 1
    return i + f(i -1)
 
result = f(999)
print(result)
posted @ 2022-05-11 16:31  酷酷的排球  阅读(2840)  评论(0编辑  收藏  举报