【问题标题】:How do you change default stack size for managed executable.net如何更改托管可执行文件.net 的默认堆栈大小
【发布时间】:2010-11-05 18:06:18
【问题描述】:

我们发现我们的一个自动生成的程序集在 new() 上抛出了 StackOverflowException。此类具有(请耐心等待)400 多个在构造函数中初始化的简单属性(大多数默认情况下(字符串)等)。

我们注意到它在 64 位上很好,但在 32 位上它会爆炸!

我们需要测试我们的用例是否可以合理地创建一个更大的默认堆栈,以便在我们重新设计代码生成器时给我们喘息的空间。

我们会特别是。如果可能的话,对涉及 app.config 的解决方案感兴趣。但我是一个现实主义者,所以一切都会好起来的。

关于堆栈溢出的原因。我们已将错误范围缩小到有问题的构造函数中。我的第一印象也是无限递归的类型。但是,我们使用 3 行控制台应用程序重现了该错误:

  • 创建一个空的类实例。
  • 在第一个工作是创建的类上调用非静态方法(克隆),并准备好将属性传入的空实例。

当它碰到第二个构造函数时会爆炸。

现在通过 .net 源代码进行调试,我们看到堆栈溢出在 Guid.NewGuid() 中,它作为第二个参数传递给构造函数。实际的代码行是对本机 CoCreateGuid() 调用的调用。

因此,虽然它可能是 CoCreateGuid() 中的错误,但我们希望从问题中消除我们的代码。我的第一个想法是大量增加堆栈的大小,看看这个错误是否再次发生。然后,既然我认为我们可以控制所有用例,就是用对象初始化替换构造函数——认为这可以减轻堆栈的压力。

注意。我们可以通过从类中删除 int 属性来阻止错误的发生。

【问题讨论】:

  • 好的,所以我在没有查看stackoverflow.com/questions/1042347/… 的建议副本的情况下投票支持关闭。对于那个很抱歉。因为这个实际上已经回答了,而另一个还没有,我认为我们应该让这个打开并关闭另一个。
  • 哎呀,重复是浏览器卡顿的情况,你真的点击返回以为我想添加更多信息 - 但显然它已发布。
  • 我知道它已经很老了,但是......可能是没有使用尾递归吗?如果您将递归函数调用作为方法中的最后一个操作,它将使用 .net 尾递归并且不会填充您的堆栈。

标签: .net stack default stack-overflow


【解决方案1】:

您可以use editbin 更改可执行文件的堆栈大小。据我所知,您不能在 app.config 中执行此操作。

另一个选项(在该页面上也提到)是创建一个具有“正确”堆栈大小的新线程。该页面提到了这种方法的优缺点。

如果只是在构造函数中设置 400 个属性是导致问题的原因,我会感到惊讶......这将是 一个 大堆栈框架 - 但除非你有 几个堆栈上的大堆栈帧,我希望它没问题。另一种可能性是你在某处有无休止的递归:)

编辑:另一种建议...

大概你在这个构造函数中有很多局部变量? (否则它不应该比任何其他调用占用更多的堆栈。)是否可以将构造函数拆分为多个方法,为每个方法设置(比如说)20 个字段?诚然,如果这些字段是只读的,那将很棘手。

如果您能告诉我们构造函数的样子,那将很有帮助。您可能还想使用 ildasm 来查看它声称该构造函数的堆栈大小。

只是检查一下,这个一个类而不是一个结构,对吧?

【讨论】:

  • 感谢您的快速回答。我已经在问题中回答了您的疑问
  • 感谢您提供更多信息。 Deffo 一个类,而不是一个结构。今天早上我要研究一下多种初始化方法。
  • 谢谢乔恩。 editbin 目前正在为我们工作——而我们正在重新设计这一代。
猜你喜欢
  • 2017-07-14
  • 2011-02-03
  • 1970-01-01
  • 1970-01-01
  • 2010-11-12
  • 1970-01-01
  • 2018-09-13
  • 2017-01-23
相关资源
最近更新 更多