如何更改托管可执行文件.net 的默认堆栈大小 [英] How do you change default stack size for managed executable.net

查看:22
本文介绍了如何更改托管可执行文件.net 的默认堆栈大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

We have discovered that one of our auto generated assemblies is throwing a StackOverflowException on new(). This class has (bear with me please) 400+ simple properties that are initialised (most by default(string) etc) in a constructor.

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

We notice that its fine on 64 bits but on 32 bits it goes bang!

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

We need to test if it's reasonable for our use case to create a larger default stack to give us breathing room while we reengineer the code generator.

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

We would esp. interested in solutions that involve app.config if possible. But I'm a realist so anything would be good.

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

Re reasons for the the stack over flow. We've narrowed the error down the constructor in question. My first impressions were also of the type of infinite recursion. However we've reproduced the error using a 3 line console app that :

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

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

It goes bang as it hits the second constructor.

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

now debugging through with the .net source code we see that the the stack overflow is in the Guid.NewGuid() which is passed as the second parameter to the constructor. The actual line of code is the call to the native CoCreateGuid() call.

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

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

推荐答案

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

You can use editbin to change the stack size for the executable. You can't do this in app.config as far as I'm aware.

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

Another option (also mentioned on that page) is to create a new thread with the "right" stack size. The page mentions the pros and cons of this approach.

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

I'd be surprised if just setting 400 properties in a constructor was the cause of the problem though... that's going to be one big stack frame - but unless you've got several big stack frames on the stack, I would expect it to be okay. The other possibility is that you've got endless recursion somewhere :)

另一种建议...

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

Presumably you have a lot of local variables in this constructor? (Otherwise it shouldn't take up any more stack than any other call.) Is it possible to split the constructor into multiple methods, setting (say) 20 fields per method? That will be tricky if the fields are read-only, admittedly.

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

If you could give us an idea of what the constructor looks like, that would help a lot. You might also want to use ildasm to see what it claims the stack size will be for that constructor.

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

Just to check, this is a class rather than a struct, right?

这篇关于如何更改托管可执行文件.net 的默认堆栈大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆