4

最適化問題の検索を高速化するために、膨大な数のインスタンスを生成するクラス B があります。数値が非常に大きくなるため、頻繁に OutOfMemory-Exceptions が発生します。回避策として、x 秒ごとにインスタンス数を減らしますが、もっと賢明なことをしたいと思います。そのために私は知りたいです:

  1. 「生きている」(作成され、まだガベージコレクションされていない) インスタンスの数を管理する良い方法は何ですか?

  2. より技術的なこと: インスタンスに使用する (たとえば) RAM の約半分を見積もるにはどうすればよいですか?

4

5 に答える 5

5

まず第一に、すべてのオブジェクトのメモリ フットプリントを可能な限り削減しようとします。膨大な数のオブジェクトを作成するため、それらの多くが同様のプロパティを共有している可能性が高く、フライウェイト パターンの完全な候補となります。ウィキペディアの記事によると、古典的な例はワープロです。

flyweight パターンの典型的な使用例は、ワープロで文字をグラフィカルに表現するためのデータ構造です。ドキュメント内の文字ごとに、そのフォント アウトライン、フォント メトリック、およびその他の書式設定データを含むグリフ オブジェクトを保持することが望ましい場合がありますが、これは文字ごとに数百または数千バイトになります。代わりに、すべての文字について、ドキュメント内の同じ文字のすべてのインスタンスによって共有されるフライウェイト グリフ オブジェクトへの参照が存在する可能性があります。内部に保存する必要があるのは、(ドキュメントおよび/またはページ内の) 各文字の位置のみです。

2 番目のステップとして、1つのオブジェクトのサイズを見積もります。C# では実際のサイズを取得するのはそれほど簡単ではないため、このコンテキストでの見積もりを強調します。この推定値を使用して、.NOutOfMemoryException

この情報は、オブジェクトが作成または破棄されるたびにオブジェクト カウンターを更新することで (およそ) 生きているオブジェクトの数を追跡することで利用できます。

class Foo {

    private static NumberOfInstances = 0;

    public Foo() {
        NumberOfInstances++;
    }

    ~Foo() {
        NumberOfInstances--;
    }
}

スレッド セーフが問題になる場合は、もちろん、この実装を少し改良する必要があります。

編集: mik z がコメントで指摘したように、ファイナライザーを介してこれを実装すると、このコンテキストで重大なパフォーマンスの問題が発生する可能性があります。IDisposableしたがって、操作でデクリメントを実装して実行する方がよいでしょうDispose。ただし、これには、オブジェクトの配置を忘れる可能性があるという欠点があります。しかし、あなたの場合、これが深刻な問題になるとは思えません。

于 2013-08-11T18:21:14.070 に答える
2

2 番目の質問の答えはわかりませんが、最初の質問の答えは次のようになります。

  • WeakReference.IsAliveプロパティを使用します。
  • デストラクタからイベントを送信します。
于 2013-08-11T17:39:09.013 に答える
0

各ノード展開はデータを照会する必要があり、すべてのオブジェクト データをメモリに保存するのではなく、定義パラメーターを各ノードに保存するだけです。ノードが選択されると、クエリからのデータが表示されます。

于 2013-08-11T17:44:14.193 に答える
0

ファクトリ パターンを利用してインスタンスを作成し、それらを追跡してメモリを管理することができます

于 2013-08-12T07:21:46.380 に答える