2012-01-27 40 views
0

我正在嘗試使用webservices SDK方法獲取VMware中虛擬機的虛擬機配置信息。我可以從我的工具的簡單控制檯應用程序,命令行界面(Powershell)獲取虛擬機配置信息。然而,當我試圖做我的UI(MMC-Snapin)相同,我得到一個StackOverflowException。你能幫我或給我建議如何調試錯誤?StackOverFlowException:它是編程錯誤(遞歸)還是沒有足夠的最大默認堆棧大小?

請注意,相同的代碼與控制檯/命令行(PowerShell)一起使用。不是從MMC UI(我負責序列化)。這與MMC的堆棧限制有關嗎?我沒有任何線索如何調試。任何想法/建議真的有幫助嗎?

我給出了下面的代碼。請注意,只要我從屬性集合中取消註釋「config」屬性,我將從MMC管理單元(UI)中獲取堆棧溢出。

問候, 夢想家


換句話說,我是否需要增加MMC UI棧的大小?


增加線程的最大堆棧大小爲8MB(8388608),沒有拋出異常。但我不高興與修復如果更大的數據來呢?

實際上將它設置爲1MB堆棧大小正在工作。所以MMC的默認堆棧大小可能很低。不知道增加到1MB是否會導致任何副作用。任何意見/想法?

順便說一句,這個異常來自我無法控制的VMWARE SDK(vimservice/vimserializers/system.xml)。

問候, 納雷什

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); 

問候, 夢想家

+0

配置符號鏈接/連接或類似?在這種情況下,你可能會遍歷導致無限循環。 – alun 2012-01-27 04:03:16

+0

你能否給我詳細說明你的意思是「配置一個符號鏈接/連接點還是類似的?」順便說一句,請注意,當從控制檯應用程序或命令行應用程序(powershell)調用相同的函數時,堆棧溢出異常不會發生。僅從UI發生。我將執行此函數的UI線程的最大堆棧大小增加到了8MB,並將其工作。但是我對解決方案感到不滿意,因爲如果更大的數據出現?當然,我可以聲明Int32.MaxValue,但理想情況下,不應該擔心堆棧大小,因爲默認值應該可以工作。再次,我不知道該怎麼做:( – Dreamer 2012-01-27 04:21:40

回答

1

得到一個堆棧溢出異常最簡單的方法是無限遞歸。那將是我會尋找的第一件事。你有異常的堆棧跟蹤嗎?如果是這樣,那會讓你立即知道。

+0

它不是無限循環,因爲它從控制檯/命令行應用程序(PowerShell)工作。它只發生在用戶界面。我增加了線程的最大堆棧大小爲8MB和它的否但是我對解決方案並不滿意,因爲如果更大的數據出現,也會出現同樣的問題?理想情況下,它不應該發生,但是我不能控制代碼,因爲它發生在VMWare Web服務sdk中(vimservice/vimserializerer/system .XML) – Dreamer 2012-01-27 04:20:15

1

由於技術原因,堆棧空間的數量是固定的。這意味着尤其是內存繁重的遞歸算法會遇到麻煩:某些輸入總是有可能超過閾值,並且儘管有大量可用RAM仍然可用,程序仍會崩潰。

在Windows上,堆棧內存保留,但通常不致力於(除了.NET)。這意味着如果您的程序需要100 MB大型堆棧,則只會佔用地址空間。其他程序仍然可以使用相同數量的RAM,因爲它們可能會在聲明可能使用最多100 MB堆棧之前使用相同數量的RAM。

在.NET中,因爲堆棧空間致力於,其他程序可以分配並在這種情況下下井100 MB的內存總量,但沒有物理RAM實際上被分配到你的算法確實需要它。

因此,增加堆棧大小並不像你想象的那麼糟糕,特別是如果你不用.NET編碼。

我已經有算法運行到堆棧限制。不幸的是,我們的算法是庫的一部分。不想要我們的調用者使用更大的堆棧來啓動它們的線程,我們重寫了該算法以在循環中使用顯式堆棧,而不是遞歸。這使算法變得更慢,更難理解。它也使調試幾乎不可能。但它完成了這項工作。

因此,用顯式堆棧重寫是一種可能性,但我建議您不要這樣做,除非您絕對必須處理傳入的數據,不管它有多大,直到可用RAM的限制,並且對設置較小硬限制。

相關問題