在堆栈大小和可能的溢出方面是不是可能有太多方法?

Posted

技术标签:

【中文标题】在堆栈大小和可能的溢出方面是不是可能有太多方法?【英文标题】:Is it possible to have too many methods in terms of stack size and possible overflow?在堆栈大小和可能的溢出方面是否可能有太多方法? 【发布时间】:2012-05-21 11:42:09 【问题描述】:

我们都知道创建促进重用的小方法是一种很好的做法,这不可避免地会导致大量方法被放置在堆栈中。但是有没有可能遇到嵌套方法调用太多导致出现***异常的场景呢?

被接受的解决方案是简单地增加堆栈大小吗?

documentation states 表示在“非常深或无限递归”期间会发生这样的异常,所以这似乎是可能的,或者 .NET 框架是否为我们动态处理堆栈大小?

我的问题可以这样总结:

有没有可能设计出这么好的程序(在 小型可重用方法的条款),这变得有必要增加 堆栈大小并因此使用更多资源?

【问题讨论】:

【参考方案1】:

.NET 堆栈大小是固定的,默认为 1 MB。

是否有可能拥有这样一个设计良好的程序(就小型可重用方法而言)对于增加堆栈大小并因此使用更多资源是必要的?

它不会将你的逻辑分解成方法。

遇到不是直接错误的堆栈溢出的唯一方法是递归。当这种情况发生(威胁)时,不要增加堆栈,而是重写代码以使用不同的方式存储数据(如Stack<T>)。

【讨论】:

【参考方案2】:

不是真的。我刚刚做了一个非常快速的测试,在 15,000 次嵌套调用之后发生了 ***Exception。

由于您拥有的方法数量之多,您不可能编写非递归嵌套 15,000 次的代码。

显然,确切的数字取决于您在堆栈上分配的许多函数局部变量。但无论这个实际数字是多少,都远远不足以满足您的建议。

【讨论】:

【参考方案3】:

在托管世界中,堆栈对性能具有特殊作用。如果您设法在堆栈上分配某些东西(使用原语或结构),则不必将其放在堆上。在堆上分配会增加 GC 压力,这平均会减慢程序的速度。

所以我可以通过在堆栈上分配很多东西来创建一个更快的程序。甚至使用 stackalloc(这是 C#/CLR 的一个鲜为人知的特性)。

有有效的案例可以做到这一点。它们很少见。仅仅说“没有有效的用途”是完全错误的。

【讨论】:

@MahmoudAl-Qudsi - 我同意,这不是我要问的 @m.edmondson,你能详细说明你想知道什么吗?我回答了您在上一段中提出的问题:是否有正当理由以需要增加堆栈大小的方式进行编程。我给出了理由。我是不是误会了什么? @usr - 我的问题是关于有这么多方法必须增加堆栈大小(因此使用更多资源)。没有询问对象存储在哪里(堆栈或堆),而是始终在堆栈上的方法指针。因此,堆存储与问题的范围无关。

以上是关于在堆栈大小和可能的溢出方面是不是可能有太多方法?的主要内容,如果未能解决你的问题,请参考以下文章

在发生堆栈溢出之前剩余堆栈的大小

什么是堆栈溢出?

如何在 c / c++ 程序中检测可能/潜在的堆栈溢出问题?

在 C++ 中将调用堆栈扩展到磁盘?

系统在此应用程序中检测到基于堆栈的缓冲区溢出。溢出...

Visual Studio C/C++ 数组大小未处理的异常堆栈溢出 [重复]