StackOverFlowException:是编程错误(递归)还是最大默认堆栈大小不足? [英] StackOverFlowException: Is it programming error (recursion) or not enough maximum default stack size?

查看:72
本文介绍了StackOverFlowException:是编程错误(递归)还是最大默认堆栈大小不足?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用webservices SDK方法获取VMware中VM的虚拟机配置信息.我能够从简单的控制台应用程序,工具的命令行界面(Powershell)获取虚拟机配置信息.但是,当我尝试在用户界面(MMC-Snapin)中执行相同操作时,出现了StackOverflowException.您能帮我还是给我一些调试错误的建议?

I am trying to get virtual machine configuration info for a VM in VMware using webservices SDK approach. I was able to get virtual machine configuration info from simple console application, command line interface (Powershell) of my tool. However when i tried to do the same in my UI (MMC-Snapin), I am getting a StackOverflowException. Can you please help me or give me suggestions how to debug the error?

请注意,相同的代码适用于控制台/命令行(powershell).不是来自MMC UI(我负责序列化).与MMC的堆栈限制有关吗?我没有任何线索如何调试此.任何想法/建议真的有帮助吗?

Please note that same code works with console/commandline (powershell). Not from MMC UI (i took care of serialization). Is it something to do with stack limitations with MMC? I dont have any clue how to debug this. Any ideas/suggestions really help?

我已经给出了下面的代码.请注意,一旦取消注释属性集合中的"config"属性,我就会从MMC管理单元(UI)中获得stackoverflow.

I have given the code below. Please note that as soon as i un-comment "config" property from property collection I am getting stackoverflow from MMC Snap-in (UI).

关于, 梦想家

换句话说,我是否需要增加MMC UI的堆栈大小?

In other words, do i need to increase the stack size for MMC UI?

将线程的最大堆栈大小增加到8MB(8388608),不会引发异常.但是我对此修复程序不满意,如果出现更大的数据该怎么办?

Increasing the max stack size of the thread to 8MB (8388608), not throwing the exception. But I am not happy with the fix as what if bigger data comes?

实际上将其设置为1MB堆栈大小是可行的.因此,MMC的默认堆栈大小可能很低.不确定增加到1MB是否会引起任何副作用.有任何意见/想法吗?

顺便说一句,例外是来自我无法控制的VMWARE SDK(vimservice/vimserializers/system.xml).

Btw, the exception is coming from VMWARE SDK (vimservice/vimserializers/system.xml) which I have no control over.

关于, 纳雷什

TraversalSpec datacenterVMTraversalSpec = new TraversalSpec();
                datacenterVMTraversalSpec.type = "Datacenter";
                datacenterVMTraversalSpec.name = "datacenterVMTraversalSpec";
                datacenterVMTraversalSpec.path = "vmFolder";
                datacenterVMTraversalSpec.skip = false;
                datacenterVMTraversalSpec.selectSet = new SelectionSpec[] { new SelectionSpec() };
                datacenterVMTraversalSpec.selectSet[0].name = "folderTraversalSpec";

                TraversalSpec folderTraversalSpec = new TraversalSpec();
                folderTraversalSpec.name = "folderTraversalSpec";
                folderTraversalSpec.type = "Folder";
                folderTraversalSpec.path = "childEntity";
                folderTraversalSpec.skip = false;
                folderTraversalSpec.selectSet = new SelectionSpec[] { new SelectionSpec(), datacenterVMTraversalSpec };
                folderTraversalSpec.selectSet[0].name = "folderTraversalSpec";

                    PropertyFilterSpec propFilterSpec = new PropertyFilterSpec();
                    propFilterSpec.propSet = new PropertySpec[] { new PropertySpec() };
                    propFilterSpec.propSet[0].all = false;
                    propFilterSpec.propSet[0].type = "VirtualMachine";
                    propFilterSpec.propSet[0].pathSet = new string[] { "name", 
                        //"config", //TODO: investigate including config is throwing stack overflow exception in MMC UI. 
                        "summary",
                        "datastore", 
                        "resourcePool" 
                    };

 propFilterSpec.objectSet = new ObjectSpec[] { new ObjectSpec() };
                propFilterSpec.objectSet[0].obj = this.ServiceUtil.GetConnection().Root;
                propFilterSpec.objectSet[0].skip = false;
                propFilterSpec.objectSet[0].selectSet = new SelectionSpec[] { folderTraversalSpec };

                VimService vimService = this.ServiceUtil.GetConnection().Service;
                ManagedObjectReference objectRef = this.ServiceUtil.GetConnection().PropCol;
                PropertyFilterSpec[] filterSpec = new PropertyFilterSpec[] { propFilterSpec };
                ObjectContent[] ocArray = vimService.RetrieveProperties(objectRef, filterSpec);

关于, 梦想家

推荐答案

出于技术原因,堆栈空间量是固定的.这意味着特别是大量占用RAM的递归算法会遇到麻烦:某些输入总是有可能超出阈值,并且尽管仍有大量可用RAM可用,程序仍将崩溃.

For technical reasons, the amount of stack space is fixed. This means that particularly RAM-heavy recursive algorithms are in trouble: it is always possible that certain inputs will overrun the threshold, and the program will crash despite lots of free RAM still being available.

在Windows上,堆栈的内存是保留的,但通常不是已提交的(.NET中除外).这意味着,如果您的程序需要100 MB的大堆栈,则仅地址空间已用完.其他程序仍可以使用与声明您可能会使用多达100 MB的堆栈之前相同的RAM.

On Windows, the memory for stack is reserved, but typically not committed (except in .NET). This means that if your program wants a 100 MB large stack, only the address space is used up. Other programs can still use the same amount of RAM as they could before you declared that you might use up to 100 MB of stack.

在.NET中,由于堆栈空间已被占用[em] ,因此在这种情况下其他程序可以分配的内存总量确实减少了100 MB,但是直到您的算法真正分配了物理RAM真正需要它.

In .NET, because the stack space is committed, the total amount of memory other programs can allocate does go down by 100 MB in this case, but no physical RAM is actually allocated until your algorithm genuinely needs it.

因此,增加堆栈大小并没有您想象的那么糟糕,尤其是如果您不是在.NET中进行编码的话.

So increasing the stack size is not as bad as you might think, especially if you're not coding in .NET.

我遇到了一个算法,该算法遇到了堆栈限制.不幸的是,我们的算法是库的一部分.不想让调用者从更大的堆栈开始线程,我们改写了算法以在循环中使用显式堆栈,而不是递归.这使得算法变慢并且难以理解.这也使得调试几乎变得不可能.但这确实完成了.

I've had an algorithm run into a stack limitation. Unfortunately our algorithm was part of a library. Not wanting to require our callers to start their threads with a larger stack, we rewrote the algorithm to use an explicit stack in a loop, instead of recursion. This made the algorithm slower and much harder to understand. It also made debugging nearly impossible. But it did the job.

所以用显式堆栈重写是一种可能,但是我建议不要这样做,除非您绝对必须处理传入的数据,无论它有多大(不超过可用RAM的限制),并且对设置较小的硬盘不满意限制.

So rewriting with explicit stack is one possibility, but I recommend against it unless you absolutely must handle the incoming data no matter how large it is, up to the limit of the available RAM, and are not happy with setting a smaller hard limit.

这篇关于StackOverFlowException:是编程错误(递归)还是最大默认堆栈大小不足?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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