递归导致的StackOverflow的分析
递归在多层次遍历时尤为重要,这里我们不讲递归的实现,来谈谈递归的内存占用情况。
如下代码,当我们运行时很简单,StackOverflowException瞬间抛出;这里确实是“瞬间”出错了,线程堆栈溢出;
首先我们要理解,一个程序是在一个进程下运行的,进程下可以有很多线程执行,但是每一个线程能占用的内存控件是有限的,大约1M,当一个线程占用超过1M时,就会StackOverflow了;存放在线程堆栈上的有方法中的值类型变量,和引用变量的指针地址。理解这些能帮我们分下,递归为什么导致StackOverflow了。
static void Main(string[] args)
{
Main(args);
}
这里我们做一个简单的分析,不考虑不重要的因素:
首先,线程执行Main方法,首先方法总没有值类型变量,只有数据args,所有只有args的指针地址存放在线程堆栈上,占4byte,Main中有调用Main方法,如此递归调用,就相当于(4+4+4……+4)bytes,最终达到1M,导致StackOverflow异常。有CLR抛出异常。
当然这里线程执行方法只是一个简单的分析,实际情况很复杂,比如,进入方法,会有一个专门的表维护方法信息,方法的返回地址,参数,局部变量,这些都占用线程堆栈空间,方法返回时,所有方法占用的内存被释放。而上述递归,永远不存在方法返回,所以资源不会被释放,最终抛出异常。
如果说上述很简单理解,那我们加俩行代码:
static void Main(string[] args)
{
GC.Collect();
GC.WaitForFullGCComplete();
Main(args);
}
这样执行方法,这个代码是我从某论坛的一个版主那里看来的,他说这样就不会导致StackOverflow了,结果下面的一群人深信不宜,我感觉递归肯定资源耗尽,只是GC不能回收线程堆栈内存,但是当我在代码上运行时,上述代码确实不报错,一直运行着,当时纳闷难道我理解错误,这不科学!我一直等着,果然过了1分钟多,我期待的StackOverflow出现了,心里窃喜。
但是我本身也不是很理解,为什么加了上面的两句话导致,要等那么久才移除,很奇怪。我问了问别人,结果实验了一下,将GC代码去掉,仅仅加一个Thread.Sleep(5),也会导致很长时间才抛出异常,费解中,最后我写了如下代码:
static int a = ;
static void Main(string[] args)
{
a++;
Console.WriteLine(++a);
Main(args);
}
我看下方法递归多少次,我电脑上是a=12万多,也就是最终方法递归了12万多次抛出了StackOverflow,所有上面的Thread.Sleep(5)执行长时间才报错也可以的出结论了,每一递归一次方法听5毫秒,递归1万次就是50秒,所以,结论不是GC回收影响递归长时间不报错,而是,每次执行GC,线程Sleep的时间,让我感觉长时间不报错。
上面问题本身没有多大意义,仅仅作为笔记记录一下,同样自己也更深入理解了内存占用。
递归导致的StackOverflow的分析的更多相关文章
- alias导致virtualenv异常的分析和解法
title: alias导致virtualenv异常的分析和解法 toc: true comments: true date: 2016-06-27 23:40:56 tags: [OS X, ZSH ...
- [转]DllMain中不当操作导致死锁问题的分析——DllMain中要谨慎写代码(完结篇)
在CSDN中发现这篇文章,讲解的比较详细,所以在这里备份一个.原文链接:http://blog.csdn.net/breaksoftware/article/details/8167641 DllMa ...
- 使用Django.core.cache操作Memcached导致性能不稳定的分析过程
使用Django.core.cache操作Memcached导致性能不稳定的分析过程 最近测试一项目,用到了Nginx缓存服务,那可真是快啊!2Gb带宽都轻易耗尽. 不过Api接口无法简单使用Ngin ...
- Mysql查询语句使用select.. for update导致的数据库死锁分析
近期有一个业务需求,多台机器需要同时从Mysql一个表里查询数据并做后续业务逻辑,为了防止多台机器同时拿到一样的数据,每台机器需要在获取时锁住获取数据的数据段,保证多台机器不拿到相同的数据. 我们My ...
- ORA-04031错误导致宕机案例分析
今天遇到一起ORACLE数据库宕机案例,下面是对这起数据库宕机案例的原因进行分析.解读.分析过程中顺便记录一下这个案例的前因后果,攒点经验值,培养一下分析.解决问题的能力. 案例环境: 操作系统 ...
- 基于.NET的大型Web站点StackOverflow架构分析(转)
Stack Overflow网址:http://stackoverflow.com/ 当前访问量:每月9500PV(每天300多万PV) 当前Alexa排名:149 所用.NET技术:C#.Visua ...
- windows phone因为墓碑化导致“正在恢复”的分析
我们在平时的WP使用过程中,会遇到一个问题 应用在切出,切回后, 有时候,会显示"正在恢复",并等待时间较长,才能回到用户切出时候的画面,但是这种情况并非常见,偶尔发生 有时候,直 ...
- HashMap-死锁导致cpu占用100%分析(转)
最近项目里面的一段千年代码出了问题,这个问题以前也出现过,不过不是那么明显,这次迁移机器由以前的4台机子变成2台以后问题被放大,最终不得不解决,特此分析一下. 先放出问题的代码 ? 1 2 3 4 5 ...
- [经验分享] MySQL Innodb表导致死锁日志情况分析与归纳【转,纯学习】
在定时脚本运行过程中,发现当备份表格的sql语句与删除该表部分数据的sql语句同时运行时,mysql会检测出死锁,并打印出日志. 两个sql语句如下: (1)insert into backup_ta ...
随机推荐
- 可以左右移动横向无缝滚动的JS图片展示代码
在酷站网站下的,具体路径忘了,稍微改了一下,让它看起来像组滑动 1)被引用的js文件ScrollPic.js ?){){i+=l.length;)I=document.cookie.length;o= ...
- 概率图模型(PGM) —— 贝叶斯网络(Bayesian Network)
概率图模型是图论与概率方法的结合产物.Probabilistic graphical models are a joint probability distribution defined over ...
- IT 达人
1. 手机与电脑多屏互动 [教程]华为多屏互动功能与PC win7的连接 要求手机和电脑必须在同一局域网内,且手机必须支持多屏互动功能. 操作步骤如下: PC 端: services.msc,启动下面 ...
- DDD实战9 经销商领域上下文
1.创建Dealer.Domain 类库项目 2.创建实体和值对象 3.安装ef的包 4.创建上下文接口(IDealerContext)之所以要创建上下文接口,是为了可替换,在其他项目总使用接口,当需 ...
- Visual C++文件扩展名解读
VisualC++文件扩展名解读 [1] .APS:存储二进制资源的资源辅助中间文件(能否加快资源加载速度). [2] .BMP:位图资源文件. [3] .BSC:浏览信息文件.由浏览信息维护工具(B ...
- 微博地址url(id)与mid的相互转换
关键字:新浪 微博 url id mid 互相转换地址:http://www.cnblogs.com/txw1958/archive/2012/12/07/weibo-id-to-mid.html 通 ...
- HDU5187 zhx's contest(计数问题)
主题链接: http://acm.hdu.edu.cn/showproblem.php?pid=5187 题意: 从1~n,有多少种排列 使得 a1~ai 满足单调递增或者单调递减. ai~an 满足 ...
- springboot 使用日志
spring boot 默认使用日志打印到console 添加application.properties文件在src/main/resoures文件夹下 logging.file=my.log 将日 ...
- WPF中使用amCharts绘制股票K线图
原文:WPF中使用amCharts绘制股票K线图 本想自己用GDI绘图, 通过数据直接绘制一张蜡柱图, 但觉得这样子的功能比较少, 所以到网上搜索一些能画出K线图的控件. 发现DynamicDataD ...
- WPF 过滤集合
<Window x:Class="ViewExam.MainWindow" xmlns="http://schemas.microsoft.com/w ...