C# 如何确定递归方法的堆栈帧大小?
我希望能够在发生C# 如何确定递归方法的堆栈帧大小?,c#,.net,clr,stack-trace,jit,C#,.net,Clr,Stack Trace,Jit,我希望能够在发生StackOverflow异常之前预测适合堆栈的递归调用的数量。为此,我需要找出堆栈上给定方法调用的“足迹” 有没有一种方法可以通过编程实现这一点?我查看了System.Diagnostics.StackFrame和System.Diagnostics.StackTrace,但找不到任何相关内容 根据经验,使用,我发现足迹在以下方面有很大不同: 32位vs 64位:~22k vs~8k帧(不同的指针大小是否会导致~3x的增加?) 调试vs发布:~22k vs~64k帧(调试构建
StackOverflow
异常之前预测适合堆栈的递归调用的数量。为此,我需要找出堆栈上给定方法调用的“足迹”
有没有一种方法可以通过编程实现这一点?我查看了System.Diagnostics.StackFrame
和System.Diagnostics.StackTrace
,但找不到任何相关内容
根据经验,使用,我发现足迹在以下方面有很大不同:
- 32位vs 64位:~22k vs~8k帧(不同的指针大小是否会导致~3x的增加?)
- 调试vs发布:~22k vs~64k帧(调试构建添加了各种特殊的模式边界检查填充+调试工具)
- 非优化与优化:
- 调试中约22k对约51k(预期-较少的调试信息)
- 发行版中有~64k对~51k(真奇怪!可能使用了一些记忆技术?)
- 调试器附加与未附加:这在jitted代码中产生了多么大的不同!
- 85k vs 258k-发布,优化
- 14k对64k-调试、优化关闭
“离线”(手动)怎么样?也许至少对于直接的、发布的、非优化的构建?为什么不将给定的方法重构为非递归实现,这样就不必担心堆栈被破坏?我会说局部变量的大小,包括返回值和返回地址。当然,类引用只算作指针(32或64位)。如果您的调用位于表达式的中间,也为正在使用的时间变量添加空间。这将是一个最大值,编译器可能会对其进行优化(例如,重用不再使用的变量的内存位置)。@Servy这是一个理论问题,这不是一个迫切需要解决的问题:)我总是在兜帽下摸索时学到一些新的东西——就像我刚才从我的小实验中得到的数据一样。打电话很容易,它是O(log(n))。因为允许更高复杂度的递归算法总是一个错误,并保证早晚会炸毁你的程序。@HansPassant[需要引证]?这听起来像是一个很好的经验法则,但什么在支持它呢?根据你的回答历史,我很确定这句话是有根据的。