爬虫遇到栈溢出(stack overflow)的问题
来源:互联网 发布:php详解socket select 编辑:程序博客网 时间:2024/05/17 15:04
今天在用python爬虫抓取网页信息的时候,出现了一个关于栈溢出的错误:
Fatal Python error: Cannot recover from stack overflow.
没有找到正确的解决方案,然后就搜索了跟栈溢出相关的知识并检查了代码,发现了问题所在:使用函数时递归调用次数过多(1000多),导致栈溢出。
在Python中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,相当于一次push压栈操作,每当函数返回,相当于一次pop出栈操作。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。
解决方案:
1.把递归调用函数改用while或者for循环来实现。
2.通过尾递归优化。尾递归是指在函数返回调用自身本身,并且return语句不能包含表达式(既return 函数名(参数))。这种情况下,编译器或者解释器,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。
下面分享一下关于栈溢出的个人理解:
在Windows程序的堆栈内存机制里,全局变量(局部的静态变量)存储在堆内存里,堆内存一般较大,不会发生溢出;而函数地址、函数参数、局部变量等信息则存储在栈内存里,栈内存就像我们常说的缓冲区,栈内存一般较小,容易发生溢出。但是效率高。
由于缓冲区溢出而使得有用的存储单元被改写,容易导致程序崩溃或者利用栈溢出进行攻击。
出现栈内存溢出的常见原因有2个:
1. 函数递归调用层次过深,每调用一次,函数的参数、局部变量等信息就压一次栈,并且没有及时出栈。
2. 局部静态变量体积太大
今天爬虫遇到的问题就属于第一种情况,可以通过尾递归优化或者改为非递归来解决。
第二种情况也比较常见,比如在函数里定义很大的局部变量(例如大数组),这种情况可以将局部变量改为静态变量(实质上也是全局变量)。
解决栈溢出的方案总体的思路也是有两个:
1.改用堆内存。这种思路比较常用,以上解决方案也是根据这种思路来做的。
2.增大栈的大小值。
- 爬虫遇到栈溢出(stack overflow)的问题
- 栈溢出的问题汇总 stack overflow
- 解决stack overflow栈溢出问题!
- 栈溢出问题(Stack overflow)【转载】
- 关于堆溢出(Stack overflow)问题的解决
- 使用PerlRegex出现“Stack overflow”堆栈溢出的问题
- Stack overflow. 更改堆栈空间解决栈溢出问题
- stack overflow的问题
- stack overflow的 问题
- 栈溢出 (stack overflow)的原因及解决办法
- 栈溢出(stack overflow)的原因及解决办法
- 堆栈溢出(Stack Overflow)的解决方法
- VC中栈溢出/Stack overflow怎么办?
- VS2005 stack overflow的问题
- VS2005 stack overflow的问题
- VC2008 的 stack overflow 问题
- VS2005 stack overflow的问题
- Debug Stack Overflow的问题
- 证明DES解密算法实际上是DES加密算法的逆
- CentOS下mysql数据库常用命令总结
- HTML5游戏的制作
- SQL数据库查询练习题
- linux 测试网络带宽时延 命令
- 爬虫遇到栈溢出(stack overflow)的问题
- 实验二 间接寻址实现学生成绩
- Java异常处理
- 利用 HBase 模拟微博的实例
- c语言实现双链表
- 实验二:顺序表的实现
- 十步完全理解 SQL
- RogueDome04
- Mayor's posters(线段树+特殊离散化)