美文网首页
递归导致内存溢出的案例和解决办法

递归导致内存溢出的案例和解决办法

作者: 黎明的叶子 | 来源:发表于2021-09-21 18:37 被阅读0次

    递归也会导致内存溢出。涉及到递归的优化,尾递归。

    尾调用:

    某个函数的最后一步是调用另一个函数。

    function fn(x){
        return g(x)
    }
    // 不是尾调用 
    function fn(x){
        return g(x)+1
    }
    

    尾调用优化

    尾调用由于是函数的最后一步操作,所以不需要保留外层函数的调用帧,因为调用位置、内部变量等信息都不会再用到了,只要直接用内层函数的调用帧,取代外层函数的调用帧就可以了。即只保留内层函数的调用帧。

    尾调用优化的意义

    如果所有函数都是尾调用,那么完全可以做到每次执行时,调用帧只有一项,这将大大节省内存。

    尾递归

    如果尾调用自身,就是尾递归。

    实例:

    阶乘函数

    // 非尾递归的写法 时间复杂度为O(n)
    function factorial(n){
        if(n===1) return 1;
        return n*factorial(n-1)
    }
    factorial(5)
    
    //尾递归的写法O(1)
    function factorial(n,total){
        if(n===1) return total
        return factorial(n-1,n*total)
    } 
    factorial(5,1)
    
    image.png

    这里可以加debugger看到,用尾递归的时候,一直都用的Local这个作用域,或者说上下文,也或者说是调用帧,一直都是这一个。所以不会当数值变大的时候,超过最大内存值。

    Fibonacci数列

    // 非尾递归的写法 时间复杂度为O(n)
    function fibonacci(n){
        if(n<=1) return 1;
        return fibonacci(n-1)+fibonacci(n-2)
    }
    Fibonacci(10) // 89 数值大会超时
    
    // 尾递归的写法 
    function fibonacci(n,result1 =1,result2=1){
        if(n<=1) return result2; 
        return fibonacci(n-1,result2,result1+result2)
    }
    

    相关文章

      网友评论

          本文标题:递归导致内存溢出的案例和解决办法

          本文链接:https://www.haomeiwen.com/subject/zwjggltx.html