2012-06-13 14 views
5

XmlDocumentオブジェクトを使用してXML文書をロードしてノードを数えるコードを記述しました。C#:Xml.Load(file)のcloseメソッド

XmlDocument xml = new XmlDocument(); 
xml.Load(textBox1.Text); 
XmlNodeList nodes = xml.SelectNodes("//File"); 
foreach (XmlNode node in nodes) 
{ 
    number_of_childs++; 
} 

私が直面している問題は、大きなファイルを読み込むときに700MBのRAMが必要になるということです。私がそのファイルを操作しようとすると、ListViewにそのデータを表示するためにそれを読み込んだら、アプリケーションは2GBのRAMのようになります。だから私はXmlDocumentを閉じてメモリを解放してRAMを解放する方法があるのだろうと思っていた。それはメモリからそのコンテンツを削除することを忘れているようなものです。

答えて

12

No. XmlDocumentクラスにはIDisposableが実装されていないため、強制的にリソースを解放する方法はありません。あなたが本当にすぐにXmlDocumentが使用しているメモリを解放する必要がある場合は、それを行うための唯一の方法は、次の手順を実行することになります。

nodes = null; 
xml = null; 
GC.Collect(); 

をガベージコレクタは別のスレッドで動作しますので、それはまだすぐには起こらないことがあります。同期が発生するガベージコレクションを強制するには、あなたのコードの実行を継続する前に、あなたはまた、のような、WaitForPendingFinalizersを呼び出す必要があります:

nodes = null; 
xml = null; 
GC.Collect(); 
GC.WaitForPendingFinalizers(); 

XmlDocument必ず一度メモリーに文書全体をロードします。ドキュメント内のノードをストリームとして繰り返し処理したい場合は、一度に少ししかロードしないでください。つまり、XmlReaderクラスのためです。しかし、あなたはそのように多くの機能を失います。たとえば、XPathでノードを選択する方法はありません。 XmlReaderを使用すると、ドキュメント内のどこにあなたが探しているものと一致するかを判断する独自のロジックを記述する必要があります。

+0

ありがとうございました。しかし、うまくいきませんでした。あなたのコードを適用しましたが、まだ同じ量のメモリを予約しています。 –

+0

@ R.Vector私の編集を参照してください。 –

+0

うん、それはうまくいったけど、アプリケーションの2番目のステップはすべてのノードを読み込んでそれをリストビューに入力することなので、問題はまだ残っていますが、xmlの各ノードを読み込み、正常にどこかに格納されていれば、メモリ管理の方が良いでしょう。 –

2

XMLを操作する必要がない場合は、XMLReaderを使用してXMLを読んでください。これは、一行で最も速く、メモリの消費量が少ない操作です。

1

オブジェクトをnullに設定する必要はありません。 GCは、文書がそれ以上使用されていないかどうかを示すことができます。これはメモリが必要になると自動的に行われますが、すぐに消去したい場合はGC.Collect()を呼び出してください。詳細は、this threadを参照してください。

+1

私はそれが一般的に大きな懸念事項ではないことに同意し、GCは最終的にそれ自身のメモリを解放しますが、手動でガベージコレクタを呼び出す場合は、GC.Collectを呼び出す前に変数をnullに設定する必要があります。そうでない場合、オブジェクトは依然として参照され、収集されません。 –

+0

@Steven Doggart、あなたのステートメントは、デバッグビルドでのみtrueです。リリースビルドでは、nullに設定する必要はありません.GCは、nullに設定せずに参照されなくなるほどスマートです。たとえば、http://stackoverflow.com/questions/5545288/garbage-collection-of-orphaned-objects-tree-nodes-works-for-the-release-exeを参照してください。 –

+0

@MattSmithそれは驚くべきことです。なぜなら、リリースビルドには、デフォルトでは、変数がもはや使用されなくなると自動的に変数を 'null'に自動的に設定する追加の最適化が含まれているからです。 –

関連する問題