递归在多层次遍历时尤为重要,这里我们不讲递归的实现,来谈谈递归的内存占用情况。

如下代码,当我们运行时很简单,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的分析的更多相关文章

  1. alias导致virtualenv异常的分析和解法

    title: alias导致virtualenv异常的分析和解法 toc: true comments: true date: 2016-06-27 23:40:56 tags: [OS X, ZSH ...

  2. [转]DllMain中不当操作导致死锁问题的分析——DllMain中要谨慎写代码(完结篇)

    在CSDN中发现这篇文章,讲解的比较详细,所以在这里备份一个.原文链接:http://blog.csdn.net/breaksoftware/article/details/8167641 DllMa ...

  3. 使用Django.core.cache操作Memcached导致性能不稳定的分析过程

    使用Django.core.cache操作Memcached导致性能不稳定的分析过程 最近测试一项目,用到了Nginx缓存服务,那可真是快啊!2Gb带宽都轻易耗尽. 不过Api接口无法简单使用Ngin ...

  4. Mysql查询语句使用select.. for update导致的数据库死锁分析

    近期有一个业务需求,多台机器需要同时从Mysql一个表里查询数据并做后续业务逻辑,为了防止多台机器同时拿到一样的数据,每台机器需要在获取时锁住获取数据的数据段,保证多台机器不拿到相同的数据. 我们My ...

  5. ORA-04031错误导致宕机案例分析

    今天遇到一起ORACLE数据库宕机案例,下面是对这起数据库宕机案例的原因进行分析.解读.分析过程中顺便记录一下这个案例的前因后果,攒点经验值,培养一下分析.解决问题的能力. 案例环境:   操作系统 ...

  6. 基于.NET的大型Web站点StackOverflow架构分析(转)

    Stack Overflow网址:http://stackoverflow.com/ 当前访问量:每月9500PV(每天300多万PV) 当前Alexa排名:149 所用.NET技术:C#.Visua ...

  7. windows phone因为墓碑化导致“正在恢复”的分析

    我们在平时的WP使用过程中,会遇到一个问题 应用在切出,切回后, 有时候,会显示"正在恢复",并等待时间较长,才能回到用户切出时候的画面,但是这种情况并非常见,偶尔发生 有时候,直 ...

  8. HashMap-死锁导致cpu占用100%分析(转)

    最近项目里面的一段千年代码出了问题,这个问题以前也出现过,不过不是那么明显,这次迁移机器由以前的4台机子变成2台以后问题被放大,最终不得不解决,特此分析一下. 先放出问题的代码 ? 1 2 3 4 5 ...

  9. [经验分享] MySQL Innodb表导致死锁日志情况分析与归纳【转,纯学习】

    在定时脚本运行过程中,发现当备份表格的sql语句与删除该表部分数据的sql语句同时运行时,mysql会检测出死锁,并打印出日志. 两个sql语句如下: (1)insert into backup_ta ...

随机推荐

  1. 关于javascript中的深拷贝问题

    一直在尝试为javascript找一个快捷可靠的对象深拷贝的方法,昨天突发奇想,把对象push到一个空数组里,然后对改数组通过concat()或slice()进行拷贝,然后取出数组的第一个元素复制给变 ...

  2. MyCat负载均衡 下篇

    MyCat负载均衡 下篇   之前在 一步一步在Windows中使用MyCat负载均衡 上篇 中已经讲了如何配置出MyCat.下面讲其相关的使用. 五.配置MyCat-eye 对于MyCat监控官网还 ...

  3. LaTex 加粗(加黑)的方式

    1. 基本 LaTeX技巧458:关于LaTeX数学字体加粗 $\mathbf $,会变为粗体,但也导致数学字母斜体形式的丢失: 使用 amsmath package 的 \boldmath 命令: ...

  4. WPF-- 合并资源字典

    原文:WPF-- 合并资源字典 1.        合并多个外部资源字典成为本地字典   语言 XAML 示例代码 <Page.Resources>   <ResourceDicti ...

  5. 新建py文件时取名千万要小心 不要和已有模块重名

    这是因为我新建了一个email.py的文件 后来我将文件名rename成了myemail.py没有看改名提示,结果导致所有的对email的import和调用全部改成了对myemail的import和调 ...

  6. HDU 1143 Tri Tiling(递归)

    意甲冠军:一些现有的1*2小盒子.求拼3*n多少个长方形的拼写. 思考: 因为它是一个递归式.肯定会遇到层的关系.仔细观察,研究发现,每层应设置2一层.(奇数层不能是矩形)而从显卡好最后一层的最后一战 ...

  7. virtualbox--在xp设置ubuntu虚拟机网络 主宿机能互通,宿机能通过主机上网Host-Only + Bridged

    由于最近要写一个简单的C/S模式的程序,刚好虚拟机装了个ubuntu12.04TLS,正好拿来当服务器测试,但是发现无法ping通.刚学习ubuntu,实在不熟,苦苦弄了2小时,才弄明白,在此记录一下 ...

  8. caffe 的架构设计及其依赖包的解析

    Caffe | Deep Learning Framework Web Classification Demos caffe(全称,Convolution Architecture For Featu ...

  9. JQuery采纳CSS实现DOM显示和隐藏要素

    今天参加了Code Review活动.阅读编写代码的同事,感到满足当前功能的实现,但是从长远来看,,无论角度还是从代码重用是来看显然不佳维修点. 有什么需要看的权利.通过选择不同的选项下拉框需求,为了 ...

  10. win10+vs2008编译比特币1.0版源码总结

    https://zhuanlan.zhihu.com/p/25074960 https://zhuanlan.zhihu.com/p/25095222 总体上是参考这两个链接,感谢大神的分享,但是中间 ...