使用可能なメモリよりも大きいXMLファイルと、DOM構造を使用してそのファイルを操作できることを前提とした大きな(!)コードベースがあります。ただし、一部のユーザーは、大きな入力サイズでOutOfMemoryExceptionを報告しています。XMLは、32ビットプロセッサで使用可能なアドレス空間よりも大きくなっています。
このケースに対処でき、膨大なXMLファイルで適切なメモリ使用を実現するために必要な場合にのみ子オブジェクトを「ハイドレイト」するDOM実装はありますか?
linq2xmlの利点を享受するために、MS XmlTeamによる2部構成の投稿で概説されている優れたソリューションがありますが、ファイルをストリーミングし、全体をロードするわけではありません。多くの盲目の路地と行き止まりの後、これはデータベースダンプから10GBを超えるxmlファイルを読み取るときに私が決めた解決策でした。
DOMオブジェクトモデルは、すべてのデータをメモリにロードしたという事実に依存しています。遅延したものの読み込みを遅らせる実装を見つけたとしても、DOM apiユーザーがDOMツリー全体をトラバースすると、メモリが不足します。
XMemorySavingXDocument
実際には、 .Load( "big.xml") `を実行するとメモリを節約できますが、最初のXPathまたはLINQクエリではOutOfMemoryExceptionが発生します。これは、クエリのいずれかが完全なDOMツリーを通過する場合に当てはまります。これが決して当てはまらないことを保証できれば、そのような怠惰なDOMツリーで逃げることができます。
私はそのような実装を知りませんが、とにかくそれがあなたの場合に役立つとは思えません。あなたが言ったように、多数のDOM ApiユーザーがすべてのノードにアクセスするDOMツリーを通り抜け、そのようなソリューションを使用すると、ほんの数ミリ秒後にOutOfMemoryExceptionが発生します。
XML DOMオブジェクトモデルは、xmlファイルをメモリ内の表現に「解凍」します。これは、元のファイルの約7倍のメモリ(x64)を消費します。32ビットの場合でも約3.5倍です。
XML DOMモデルが非常に肥大化している理由は、各domノードが子、親、および属性を認識しているためです。これは、すべてのDOMノードのオブジェクト参照であり、かなりのコストがかかります。
管理対象クラスオブジェクトは、インスタンスごとに少なくとも12/24バイトを消費します。各ノードポインタは合計メモリ消費量にさらに4/8バイト(x86、x64)を追加するため、大きなxmlファイルを使用するとメモリがすぐに不足します。.NETオブジェクトのサイズの詳細については、この記事を参照してください。
DOMは大きなXMLファイルには適していませんが、現在のアーキテクチャではDOMが必要なので、DOMを抽象化して、関心のあるものを抽出(および潜在的に変更)するAPIに置き換える必要があるのではないかと心配しています。大きな組織では、このトピックをアーキテクトに提示し、それらを主要な再設計として提示することができます。
建築家や経営陣からのコミットメントを得ることがさらに幸運であるなら、あなたが次の大きなバックログ項目を処理するために一度も行ったことがない国のアウトソーシングされたプログラマーもいます;-)。
データ形式がパフォーマンスにどの程度影響するかを数値で示すために、100万個の整数を含むファイルを作成しました。私は3つの異なるデータ形式を使用しました
それから私は64ビットプロセスでそれらを読みました
メモリ消費量は、1.2 GBのメモリピークにつながるXDocument.Loadを除いて、約200MBで横ばいでした。あなたのパフォーマンスの目標は異なるかもしれませんが、私は最初にストリーミングXmlReaderを介してXmlのものをはるかに高速にロードできるバイナリ形式に変換します。
これは最適なソリューションではありませんが、過去にXMLファイルを文字列として読み込み、正規表現を使用して部分を独自のDOMオブジェクトに分割していました。
おそらく、XPathも使用できますか?(https://developer.mozilla.org/en-US/docs/Using_XPath)