2009-05-12 9 views
4

私は、たくさんのデータを保持する汎用辞書を持っています。私は、辞書のサイズがあまりにも多くのメモリを占有し始めると、項目を削除する(私はどの項目を決定するかを知っています)ようにしたいと思います。C#/。NET:辞書のメモリ使用量

私のプログラムがこの辞書で使用されるRAMを監視する最も良い方法は何ですか?

ディクショナリの各項目は可変サイズです。

+0

なぜasp.netキャッシュを使用しないのですか? httpコンテキストなしで動作し、あなたが求めている機能を持っています...(http://www.hanselman.com/blog/UsingTheASPNETCacheOutsideOfASPNET.aspx) –

答えて

5

一つの方法は、hereを示すDictionary.Count

によって各項目のサイズを動作し、乗算:

メモリ内のオブジェクトの使用の サイズを決定するための近似方法により を行うことができます オブジェクトの作成の前後に合計メモリ をチェックします。次の例では、 はfooという名前のクラスがあるとみなされます。

long StopBytes = 0; 
foo myFoo; 

long StartBytes = System.GC.GetTotalMemory(true); 
myFoo = new foo(); 
StopBytes = System.GC.GetTotalMemory(true); 
GC.KeepAlive(myFoo); // This ensures a reference to object keeps object in memory 

MessageBox.Show("Size is " + ((long)(StopBytes - StartBytes)).ToString()); 

C#は、それはC/C++でするように動作します「はsizeof」演算子を持っている、しかし、それはそのタイプのフィールドがなるというサイズを返します。したがって、参照型(クラスではなく構造体)では、ポインタのサイズ(32ビットシステムでは4)が常に返されます。代わりにSystem.Runtime.InteropServices.Marshal.SizeOf()を使用してください。

+1

"各項目のサイズを調整してください。"どうやって? – BFree

+0

これはスレッドセーフではなく、実際には負の数を返すことができます。 – jellomonkey

+1

@jellomonkey:真だがそうは思わない。私は彼が実際の生産コードでこれを行うことを勧めません。むしろサイズを決定するためのテストプロジェクト(頻繁に変更されないことを前提としています)。 –

-1

ディクショナリに何かを追加するときは、アイテムのサイズを計算し、ディクショナリからこのアイテムを削除するときに、追加された各アイテムの合計を単一のint値として保持します。

+0

アイテムのサイズはどのように計算されますか? – stakx

1

オブジェクトの実際のサイズを示すAPIはありませんが、オブジェクトの作成前後で使用されているメモリの量を測定することで判断できます。ただし、スレッドセーフではありません。

System.Runtime.InteropServices.Marshal.SizeOf()を使用すると正確なサイズが得られなくても正確な比較ポイントが得られるので、次のように言うことができます。オブジェクトのサイズX%だけ増加し、Y個の要素を除去する。

また、合計を維持しようとすることもできますが、コレクション内のアイテムが編集可能な場合は、すべての追加、削除、および編集が計算に含まれていることを確認する必要があります。追加したり削除したりするアイテムを適切に測定する問題が残っています。上記のように、これを正確に行うAPIはないと思います。