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

如下代码,当我们运行时很简单,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. tomcat启动时自动加载一个类 MyServletContextListener

    目的: 我们知道在tomcat启动后,需要页面请求进行驱动来执行操作接而响应.我们希望在tomcat启动的时候能够自动运行一个后台线程,以处理我们需要的一些操作.因此需要tomcat启动时就自动加载一 ...

  2. 将普通java工程转换成maven工程

    在MyEclipse10中将Maven项目转成普通Java项目后,想将Java项目转成Maven项目,结果一下子傻眼了.根本就没有攻略中提到的config标签.仔细一看,喵咪的,人家用的是Eclips ...

  3. node lesson4--eventproxy不懂

    var express = require('express'); var superagent = require('superagent'); var cheerio = require('che ...

  4. 关于java中继承抽象类和实现接口的区别

    简单来说,继承就是“是不是”,实现就是“有没有”.(一个大神说的,我觉得很生动很形象 海子大神链接http://www.cnblogs.com/dolphin0520/p/3811437.html)

  5. WPF MVVM系列文章

    网上搜到了MSDN Magazine上Laurent Bugnion的系列文章. 以下为关于WPF的优秀实践,很有必要阅读. 很吸引人的标题有: IOC Containers and MVVM Mes ...

  6. Android framework召回(3)binder使用和IBinder BpRefbase IInterface INTERFACE 之间的关系

    status_t AudioSystem::setStreamVolumeIndex(audio_stream_type_t stream, int index, audio_devices_t de ...

  7. JS简单验证password强度

    <input type="password" id="password" value=""/><button id=&qu ...

  8. Android到您的计算机使用命令行屏幕捕获和出口

    声明:本博客为原创博客,未经同意.不得转载! 原文链接为http://blog.csdn.net/bettarwang/article/details/27819525 大多数人最经常使用的截屏方法可 ...

  9. #747 –在WPF程序的触摸操作中使用惯性移动 (Implementing Inertia during Touch Manipulation)

    原文:#747 –在WPF程序的触摸操作中使用惯性移动 (Implementing Inertia during Touch Manipulation) 原文地址:https://wpf.2000th ...

  10. Notepad++ 自定义关键字

    Notepad++是一款輕便好用的編輯器,但可能有些語言的關鍵字不全,比方SQL中,默認關鍵字沒有Merge. 怎样給Notepad++中的語言添加關鍵字,而不是大動干戈自定義一個語言? 步驟: Se ...