代码之家  ›  专栏  ›  技术社区  ›  Preet Sangha

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

  •  4
  • Preet Sangha  · 技术社区  · 15 年前

    我们发现一个自动生成的程序集在new()上引发stackOverflowException。这个类有400多个简单的属性,这些属性是在构造函数中初始化的(大多数是默认的(字符串)等)。

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

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

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

    重述叠加过流的原因。我们已经缩小了所讨论的构造函数的错误范围。我的第一印象也是无限递归的类型。但是,我们使用3行控制台应用程序复制了错误:

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

    当它碰到第二个构造器时,它就爆炸了。

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

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

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

    1 回复  |  直到 15 年前
        1
  •  2
  •   Jon Skeet    15 年前

    你可以 use editbin 更改可执行文件的堆栈大小。据我所知,你不能在app.config中这样做。

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

    如果只是在一个构造函数中设置400个属性是导致这个问题的原因,我会很惊讶…那将是 大堆栈帧-但除非 几个 堆栈上的大堆栈帧,我希望它是好的。另一种可能是你在某个地方有无限的递归:)

    编辑:其他建议…

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

    如果你能给我们一个关于构造器是什么样子的概念,那会有很大帮助。您可能还希望使用ildasm来查看它声明该构造函数的堆栈大小是什么。

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