如何更改托管可执行文件的默认堆栈大小.net

Pre*_*gha 5 .net stack-overflow stack default

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

我们注意到它在 64 位上运行良好,但在 32 位上运行却很糟糕!

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

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

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

  • 创建类的空实例。
  • 在类上调用非静态方法(克隆),该类的首要任务是创建空实例并准备将属性传递给其中。

当它击中第二个构造函数时,它会爆炸。

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

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

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

Jon*_*eet 4

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

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

如果只是在构造函数中设置 400 个属性是问题的原因,我会感到惊讶...这将是一个大堆栈帧 - 但除非堆栈上有几个大堆栈帧,否则我会期望它没事。另一种可能性是你在某个地方有无限的递归:)

编辑:另一个建议......

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

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

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