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

如下代码,当我们运行时很简单,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的时间,让我感觉长时间不报错。

上面问题本身没有多大意义,仅仅作为笔记记录一下,同样自己也更深入理解了内存占用。

最新文章

  1. [转]俞敏洪:我和马云就差了8个字... [来自: news.mbalib.com]
  2. Some Delphi tips
  3. 友情提醒:欲开发android5.0以上应用,请全部更新开发工具至最新
  4. BLOB或TEXT字段使用散列值和前缀索引优化提高查询速度
  5. 精华阅读第 9 期 |滴滴出行 iOS 客户端架构演进之路
  6. 分布式ActiveMQ集群
  7. 关于Spring中AOP的理解
  8. 【转】android adb命令
  9. [LeetCode]题解(python):019-Remove Nth Node From End of List
  10. Netty 系列一(核心组件和实例).
  11. Android相关 博客收藏
  12. 国外优秀C/C++网站
  13. 《图解CSS3:核心技术与案例实战》
  14. 2017 年 机器学习之数据挖据、数据分析,可视化,ML,DL,NLP等知识记录和总结
  15. LeetCode OJ:Valid Number
  16. C#使用zookeeper
  17. 某C电面记
  18. springboot-5-整合jpa
  19. NYOJ467 中缀式变后缀式 【栈】
  20. maven-windows使用

热门文章

  1. error: openssl/md5.h: No such file or directory
  2. SpringCloud学习笔记-zuul网关
  3. delphi 10.2 创建并使用资源文件(一共22种格式,RCDATA是自定义格式)
  4. .net 程序员 两年工作总结
  5. Java transient关键字【转】
  6. ddraw 视频下绘图 不闪烁的方法
  7. matlab 矢量化编程(一)—— 计算 AUC
  8. WPF 使用字体引发的 CLR20r3 问题排查
  9. sql count(1)不要和查询数据混用 非常耗时
  10. php获取一个月前的时间戳,获取三个月前的时间戳,获取一年前的时间戳