【问题标题】:How to change stack size for a .NET program?如何更改 .NET 程序的堆栈大小?
【发布时间】:2011-02-03 03:46:32
【问题描述】:

我有一个执行 20 亿次递归调用和堆栈溢出的程序。我进行了更改,然后它仍然需要 40K 递归调用。所以我可能需要几 MB 堆栈内存。我听说堆栈大小默认为 1MB。我尝试在网上搜索。有人说去属性->链接器......在visual studio中,但我找不到它。

有人知道怎么增加吗?另外我想知道是否可以在我的 C# 程序中设置它?

附:我使用的是 32 位 winXP 和 64 位 win7。

【问题讨论】:

    标签: .net resize stack stack-overflow


    【解决方案1】:

    从 .NET 2.0 和 Win XP 开始设置堆栈大小的最简单方法是生成一个具有您想要的堆栈大小的新线程:-

    using System.Threading;
    
    Thread T = new Thread(threadDelegate, stackSizeInBytes);
    T.Start();
    

    要更改整个程序的堆栈大小,您必须使用 editbin:-

    EDITBIN.EXE /STACK:<stacksize> file.exe
    

    【讨论】:

    • 对于那些走editbin路线的人,您需要在Visual Studio安装程序中下载Visual C++工具集。您也可以将其作为EDITBIN.EXE /STACK:&lt;stacksize&gt; $(TargetName) 放在您的后期构建步骤中
    • @CameronAavik 添加到您的评论中,我需要将 SDK 工具文件夹添加到我的路径中,重新启动 Visual Studio 以查看此更改,并使用 $(TargetPath) 而不是 $(TargetName)
    • @JamieThomas 依次添加到您的评论中,而不是更改路径,您可以在构建后事件命令行中包含:调用“$(DevEnvDir)..\tools\VsDevCmd.bat”跨度>
    • 限定我自己的评论:这可能并不总是有效。将 PATH 环境变量设置为包含包含 editbin 的文件夹将起作用。然后,可以在 .csproj 文件中使用带有 Name="PostBuild" 和 AfterTargets="PostBuildEvent" 的 Target 元素将命令包含在 Exec 元素中。
    【解决方案2】:

    没有编译器选项可以做到这一点。您可以edit it after the fact using editbin /stack,或者为您的算法创建一个单独的线程,并在Thread constructor 中指定更大的堆栈大小。

    话虽如此,您可能希望展平您的递归函数...如果您现在遇到堆栈溢出,那么很难知道任何堆栈大小在长期内都是合适的。这只是一个创可贴的解决方案。

    【讨论】:

      【解决方案3】:

      您很可能应该尝试使用循环而不是递归。

      【讨论】:

      • 让我们更精确一点:问题不在于递归本身,或者迭代次数(毕竟,仍然会有 20 亿次迭代转换为循环后)。真正的问题是编译器可能不会生成尾调用;正因为如此,递归与大量迭代相结合才会成为问题。
      【解决方案4】:

      我知道在 VS 中您可以设置任意堆栈大小(编辑:对于 C++ 程序)。但是,我建议您使用自动回收堆栈空间的尾调用(即 return MyFunc(args); )。然后,您将使用一些堆分配的对象来保存状态。

      【讨论】:

      • 一般来说,我认为 .NET 编译器不会优化尾递归调用。至少,C# 和 VB.NET 没有。
      猜你喜欢
      • 2011-07-27
      • 2018-09-13
      • 1970-01-01
      • 2012-08-25
      • 2016-05-27
      • 2017-03-18
      • 2010-10-30
      • 2010-11-05
      相关资源
      最近更新 更多