0

CLR Profiler を使用していくつかの実験を行った結果、次のことがわかりました。

Node[,] n = new Node[100,23]; //'84,028 bytes, is not placed in LOH
Node[,] n = new Node[100,24]; //'86,428 bytes, is 

    public struct Node {
        public int Value;
        public Point Point;
        public Color Color;
        public bool Handled;
        public Object Tag;
    }

実行時に、構造体の配列 (または任意の配列) がラージ オブジェクト ヒープ (LOH) に割り当てられたことを確認するにはどうすればよいですか?

4

3 に答える 3

2

85,000 バイトを超えるオブジェクトはすべて LOH に格納されます。.Net メモリ管理に関する素晴らしいブログ投稿を次に示します。

于 2010-05-06T00:33:54.707 に答える
1

あなたのコメントから、私はあなたが実際にオブジェクトがLOHに行くかどうかを知る必要はないと思います。それがアプリケーションの速度低下の実際の原因であるかどうかは、ユーザーが「大きすぎる」値を入力したときにユーザーに警告を表示するだけの場合は、関係ありません。

ですから、もう少し簡単なことを提案します。少し試行錯誤してカットオフ値を決定します。試行錯誤の値を超えるサイズを入力した場合は、警告を表示します。

実際のパフォーマンスの問題については、1つの大きな2次元配列を割り当てる代わりに、「小さな」1次元配列の束を割り当てるだけで済みます。それ以外の:

Node[,] n = new Node[100,100]; // this will go the LOH

あなたはこれをするでしょう:

Node[][] n = new Node[100][];
for(int i = 0; i < n.Length; i++) {
    n[i] = new Node[100];  // none of these will be on the LOH
}

合計で同じ数のノードがありますが、LOHには何も起こりません。個人的には、パフォーマンスはそれほど変わらないことがわかると思いますが、試してみる価値はあるかもしれません。

于 2010-05-06T01:07:42.987 に答える
1

配属後すぐにわかります。GC.GetGeneration(object) オーバーロードを使用して、オブジェクトが配置されている世代番号を取得します。LOH の場合、これは 2 になります。

Node[,] n = new Node[100,23]; 
// GC.GetGeneration(n) should give 0
Node[,] n = new Node[100,24]; 
// GC.GetGeneration(n) should give 2

これにはいくつかの制限があり、プロダクション コードでは決して適切な方法ではないことに注意してください。後でその番号を照会すると、オブジェクトは既に Gen 0 から Gen 2 に移動されている可能性があります。Gen2 (スモール オブジェクト) ヒープと LOH を区別する方法はありません。また、LOH でオブジェクトに対して返される数は、テストしたすべての .NET バージョンで 2 です。しかし、これは実際の仕様では見つけられなかったので、これも変更の問題かもしれません。

于 2011-01-27T10:50:27.663 に答える