这几天在用node.js写一个递归遍历文件树的功能,一直都有一个概念,就是递归次数过多,程序可能崩溃。但是一直没有仔细想过这个问题的原因,这里又多思考了一下,参考一下维基百科,每次函数递归调用的时候,在调用栈的顶部都要增加一条记录,记录子函数的返回地址,这样,随着递归深度的加深,用栈中一次讲调用函数返回地址入栈,当入栈次数过多,超过栈顶时,便会报栈溢出错误。
代码1: 递归判断数字是否是偶数,是返回1,否返回0
测试发现,当number足够大的时候,程序运行一段时候就会报堆栈溢出的错误。 由于node.js屏蔽了堆栈分配等细节,大概可以猜测,因为随着递归深度加深,return前不断执行子函数,不断有局部变量和子函数返回地址等入栈,所记录的上下文环境越来越大,超过栈顶后便报错了。参考网上的例子,要解决这样的问题,关键就是函数返回的时候,直接返回一个结果,而不是执行一个子函数后返回,这样就避免了在调用栈栈顶对子函数的返回地址进行记录,通过这个方法,避免堆栈溢出。
代码2: 递归判断数字是否是偶数,是返回1,否返回0 , 使用闭包,递归调用放在匿名函数中。
测试发现,此时运行不在出现堆栈溢出的错我,但是由于闭包记录了一些上下文,不断执行ret()的时候,闭包链也越来越长,无限次运行时,可能会出现内存泄漏。