2012-01-27 14 views
0

私は、WebサービスSDKのアプローチを使用してVMwareのVMの仮想マシン構成情報を取得しようとしています。私は簡単なコンソールアプリケーション、私のツールのコマンドラインインターフェイス(Powershell)から仮想マシンの構成情報を取得することができました。しかし、UI(MMC-Snapin)で同じことをしようとすると、StackOverflowExceptionが発生します。エラーをデバッグする方法を教えてください。StackOverFlowException:プログラミングエラー(再帰)または最大デフォルトスタックサイズが不足していますか?

コンソール/コマンドライン(powershell)と同じコードが動作することに注意してください。 MMCのUIからではありません(私は直列化の世話をしました)。それはMMCのスタック制限に関係していますか?私はこれをデバッグする方法を知りません。どんなアイデアや提案が本当に助けになる?

私は以下のコードを与えました。 MMCスナップイン(UI)からstackoverflowが取得されているプロパティのコレクションから "設定"プロパティをコメント解除するとすぐに注意してください。

よろしく、言い換えれば ドリーマー


は、私は、MMCのUIのスタック・サイズを大きくする必要がありますか?


が例外を投げないで、8メガバイトのスレッドの最大スタックサイズ(8388608)を増やします。しかし、大きいデータが来たらどうすればいいのですか?と修正されましたか?

実際、1MBのスタックサイズに設定しています。 MMCのデフォルトのスタックサイズはおそらく低いです。 1MBに増えても影響はありません。コメント/考え?

Btw、例外は私が制御できない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

+0

あなたは「シンボリックリンクかジャンクションかそうであるか? Btwは、同じ関数がコンソールアプリケーションまたはコマンドラインアプリ(powershell)から呼び出されたときにスタックオーバーフロー例外が発生しないことに注意してください。 UIからのみ発生します。私は、この関数を実行するUIスレッドの最大スタックサイズを8MBに増やして動作させました。しかし、大きなデータがあれば、私は解決策に満足していません。もちろん、Int32.MaxValueに宣言することはできますが、デフォルトではスタックサイズについて心配する必要はありません。再び、私は何をすべきかわかりません:( – Dreamer

答えて

1

スタックオーバーフロー例外を取得する最も簡単な方法は無限再帰です。それが私が探している最初のものです。あなたの例外はスタックトレースを持っていますか?その場合、すぐにあなたに知らせることができます。

+0

それはコンソール/コマンドラインアプリ(powershell)から動作するので無限ループではありません。UIからのみ発生します。私はスレッドの最大スタックサイズを8MBに増やしましたしかし、私はVMWare webservices sdk(vimservice/vimserializerer/system)でコードが制御されることはありません。 .xml) – Dreamer

1

技術的な理由から、スタック領域は固定されています。これは、特にRAMが重い再帰アルゴリズムが問題になっていることを意味します。特定の入力がしきい値を超え、プログラムが空きRAMが残っていてもクラッシュする可能性が常にあります。

Windowsの場合、スタックのメモリはと予約されていますが、通常はコミットされません。(.NETを除く)。つまり、プログラムが100 MBの大きなスタックを必要とする場合は、アドレス空間だけが使い果たされます。他のプログラムでは、最大100 MBのスタックを使用する可能性があると宣言する前に、同じ量のRAMを使用することができます。

スタック空間がであるため、がコミットされているため、他のプログラムが割り当てることができるメモリの総量は100 MB減少しますが、本当にアルゴリズムが本当に必要になるまで物理RAMは割り当てられません。

スタックサイズを増やすことは、特に.NETでコーディングしていない場合は、思ったほど悪くありません。

私はアルゴリズムにスタック制限をかけました。残念ながら、私たちのアルゴリズムはライブラリの一部でした。私たちの呼び出し側にスレッドをより大きいスタックで開始させることを要求したくない場合、再帰の代わりにループ内で明示的なスタックを使用するアルゴリズムを書き直しました。これにより、アルゴリズムの速度が遅くなり、理解がより困難になりました。また、デバッグはほとんど不可能でした。しかし、それは仕事をした。

明示的なスタックで書き直すことも可能ですが、大きさにかかわらず受信データを処理しなければならないか、使用可能なRAMの上限までは絶対に必要としない限り、ハードリミット。

関連する問題