在c#中使用单一方法会发生***异常吗?
Posted
技术标签:
【中文标题】在c#中使用单一方法会发生***异常吗?【英文标题】:Will the *** exception occur by using single method in c#? 【发布时间】:2020-04-27 19:20:06 【问题描述】:当一个方法被递归调用(无限次)时会发生 *** 异常(每个递归调用分配不同的堆栈帧,在这种情况下使用多个堆栈帧)。众所周知,每个方法调用都会分配一个堆栈帧。堆栈是否可以使用单一方法(使用单个堆栈帧)溢出。
【问题讨论】:
“为每个方法分配一个超级堆栈帧” - 这是不正确的。为每个方法 call 分配一个堆栈帧。溢出的最常见原因是在没有合适的中断条件的情况下调用自身的方法。 “当一个方法被递归调用时(无限次)”——它不必是无限的——只是“太多” 另见this question 好酷,很多次 【参考方案1】:使用单一方法可以溢出堆栈吗
当然:
static unsafe void Main()
for(int i = 0; i < 50; i++)
// fails on i=18 for me
long* ptr = stackalloc long[10 * 1024];
当堆栈被完全消耗时会发生堆栈溢出。有多种方法可以做到这一点;递归只是其中之一。 stackalloc
在当前堆栈帧处创建一个指向(或最近:跨越)内存块的指针,扩展当前堆栈帧;当您从分配它的方法返回(或抛出等)时,它将在概念上被回收(尽管实际上,这只是意味着更改单个数字)。
另一种方法是创建一个荒谬的超大值类型:
static class P
static void Main() => Foo();
static void Foo() => Bar(default);
static void Bar(FatStruct2097152 a) => Console.WriteLine(a);
struct FatStruct64
private long a, b, c, d, e, f, g, h;
struct FatStruct512
private FatStruct64 a, b, c, d, e, f, g, h;
struct FatStruct4096
private FatStruct512 a, b, c, d, e, f, g, h;
struct FatStruct32768
private FatStruct4096 a, b, c, d, e, f, g, h;
struct FatStruct262144
private FatStruct32768 a, b, c, d, e, f, g, h;
struct FatStruct2097152
private FatStruct262144 a, b, c, d, e, f, g, h;
【讨论】:
How to change stack size for a .NET program? 可用于让不太引人注目(不是unsafe
)的方式也足够快地实现它。
马克-很好!我不记得struct
的大小是否有限制,以及是否有一个与默认堆栈大小相差多远,所以尽管您无论如何都需要缩小堆栈...但现在懒得尝试:)跨度>
我对这种可憎的东西(当然是 FatStruct)的反应基本上是this scene from Jurassic Park?
所以现在栈内存是栈帧内存的集合。如果调用了一个新的方法调用了一个栈帧分配,这个实际意义是什么?(是把下一个块分配给新的方法调用?)
@NikhilChitneni 堆栈帧不是这样“分配”的——堆栈只是一块连续的内存;没有块——它只是一块虚拟内存;方法调用只需占用目标和参数所需的空间,(一定数量的)簿记空间,(一定数量的空间)用于方法声明的局部变量,然后它只是递增(从技术上讲,递减 -堆栈向下增长,因为原因)指向该空间内当前语义框架的指针以上是关于在c#中使用单一方法会发生***异常吗?的主要内容,如果未能解决你的问题,请参考以下文章
JAVA语言如何进行异常处理,关键字throws,throw,try,catch,finally分别代表啥意义在try块中抛出异常吗