1

特に、私は次のようなシナリオを考えています。

    unsafe struct Foo
    {
        public int Bar;

        public Foo* GetMyAddr()
        {
            fixed (Foo* addr = &this)
                return addr;
        }
    }

管理されていないメモリに格納されているFooを想定して、GetMyAddrの固定ステートメントの評価に何が関係しているかを把握しようとしています。私はプログラマーとして、この構造体がマネージヒープ上にないことを知っています。最も効率的な方法で、アンマネージメモリ内のアドレスを取得する必要があります。ここで使用されているロック操作や不可分操作があると、完全に不適切になるので、特に心配です。

4

4 に答える 4

7

これはあなたが思うことをしません。「fixed」ステートメントは、「fixed」ステートメント自体の期間中のみ管理対象オブジェクト(this)を固定します。これは、「return」するとすぐに終了します。詳細については、MSDNのドキュメントを参照してください。

あなたはすでにあなたの「Foo」がアンマネージドメモリにあると言っています。これは、マネージドGCがそれをあなたの上で動かすことはないということを意味します。その場合、「&this」を直接返すことはできませんか?または、管理対象外のオブジェクトを管理対象オブジェクトにマーシャリングすることを検討することもできます。あなたがしていることについてもう少しコンテキストを与えてください。そうすれば、私たち全員がより具体的なアドバイスを与えることができます。

于 2010-07-23T23:28:14.080 に答える
2

構造がアンマネージメモリに存在する場合、式&thisは意味を持ちません。そこに割り当てる方法はありません。管理された構造の重要な特性は、それらのメモリレイアウトが検出できず、その構造の管理されていないビューと互換性がないことです。CLRは、メンバーの配置中に最小サイズを取得するのに適していると判断した場合に、フィールドを再配置します。後でフィールドがパディングに収まる場合は、実際にはフィールドが交換されます。

Marshal.PtrToStructureを通過して、管理されていない構造体を管理されたバージョンに変換することはできません。Marshal.SizeOfは、管理されていないレイアウトに対してのみ正確です。

于 2010-07-23T23:46:07.947 に答える
0

基本的にオーバーヘッドはまったくありません。修正済みとは、「ポインタが指す場所をメモリ内に固定し、再配置しない」ことを意味します。他のすべてのマネージドポインタは、メモリを移動することを決定した場合、ガベージコレクタによって自由に「曲げられる」ことができます。修正するとこれが防止されるため、基本的にはこの(可能な)オーバーヘッドを「節約」します。

固定ポインタの実装についてはわかりませんが、最も単純なケースでは、メモリブロックをブラックリストに登録するだけです。これは、通常のマネージポインターと比較してそれほどコストがかかりません。

一方、ローカリゼーションの増加、フラグメンテーションの削減など、メモリ管理の観点からGCが実行することを決定する可能性のあるあらゆる種類の最適化を防ぎます。

于 2010-07-23T23:25:08.413 に答える
0

私はマイクロベンチマークを設定し、アンマネージメモリ内の構造体で使用した場合のfixedのオーバーヘッドを測定しました。これは非常に低く、fixed(this)を返すのは単にこれを返すよりもわずか10倍高価です。これは私のユースケース(構造体のアドレスを使用したハッシュ)では許容できます。実装方法を知ることはできませんでしたが、この場合は十分に高速であるようです。

于 2010-07-28T16:34:54.743 に答える