1

.netランタイムに、オブジェクトをメモリに再配置しないように指示する方法はありますか?

IMHO-オブジェクトはいつまでに再配置できますGC

  • ある世代から別の世代への移行
  • キューに移動されfinilization-queueています。f-reachable
  • そうでなければ(多分最適化メカニズム?)。

    また、不変(文字列)は毎回自動的に再作成されるので、新しい場所に作成する必要があると思いました。

(単なる理論上の質問)

4

3 に答える 3

3

実装の詳細として、.Net Frameworkは、ガベージコレクションの最終段階でメモリ内のオブジェクトを移動できます。ただし、これは必ずしも世代間を移動することを意味するわけではありません。第2世代のGCを実行すると、世代を変更しなくても、第2世代のオブジェクトが移動されます(第2世代を超える場所がないため)。

ファイナライズキューとf-reachableキューはこれとは関係がなく、オブジェクト自体ではなく、オブジェクトへの参照のみが含まれます。

これが不変オブジェクトと何の関係があるのか​​わかりません。ランタイムは、それらに特別な処理を行いません(文字列を除く)。

オブジェクトを再配置しないようにランタイムに指示すること(オブジェクトの「ピン留め」とも呼ばれます)は異常な要件であり、GCのパフォーマンスに悪影響を与える可能性があるため、非常に正当な理由があります。安全でないコードでオブジェクトを一時的に固定するには、fixedステートメントを使用できます。永続的に、または安全なコードからそれを行うにはGCHandle.Alloc()、を指定してを使用できますGCHandleType.Pinned

于 2012-07-22T09:56:09.267 に答える
1

ピン留めされたオブジェクトは、空き領域の大きなチャックを作成するために移動しないようにgcに指示します。それらはFixedキーワードを使用して作成されます。

便利なシナリオ

アンマネージ関数に渡す必要のある配列の整数があり、アンマネージ関数が配列の値を読み取って変更を行うシナリオを考えてみましょう。配列が固定されていない場合、配列へのポインタがGCによって移動されたため、変更された値を書き戻すことはできません。

于 2012-07-22T09:38:57.327 に答える
0

これが質問のコンテキストで役立つかどうかはわかりませんが、管理されたシナリオでは、Marshallクラスを使用してメモリを割り当て、構造を割り当てられたメモリに移動して、ポインタを戻すことができます。この構造はgcによって移動されません。後で、前のポインタを使用して、割り当てられたメモリから構造を取得できます。

于 2012-07-22T09:34:03.707 に答える