2

したがって、C#で参照オブジェクトの物理アドレスを取得することについてこの質問を数回見ましたが、一般的なコンセンサスは、のアドレスを取得できるように呼び出すことができないため、これは不可能であると思われGCHandle.AllocますGCHandleType.Pinned固定されたオブジェクト。

私が奇妙だと思うのは、Visual Studio デバッガーでオブジェクトをローカル ウィンドウからメモリ デバッグ ウィンドウにドラッグし、参照オブジェクトのアドレスとメモリを確認できることです。イミディエイト ウィンドウに入力して&obj、オブジェクトの実際のアドレスを取得することもできます (このアドレスは、[メモリ] ウィンドウに表示されているアドレスに正しく対応しています)。

しかし、コンパイルされたコードで同じ呼び出しを行うことができないのはなぜですか...つまり:

object someObject = new Object();
&obj; // Compiler Error: Cannot take the address of, get the size of, or declare a pointer to a managed type ('object')

Immediate\Memory Window はマネージ型のアドレスを取得し、メモリのレイアウトを表示することもできますが、C# ではこれを行うことはできません。C#で参照オブジェクトのこの実際のアドレスを取得する方法はありますか?

4

2 に答える 2

3

デバッガーには、独自のコードよりも優れた利点があります。コードが実行されていない状態でフリーズしている間、プロセスの状態を確認できます。したがって、オブジェクトのアドレスを取得することは問題ではなく、ガベージ コレクターが実行されて無効化されることはありません。

于 2012-09-28T17:29:31.707 に答える
0

Carbage Collector は、オブジェクトの有効期間を処理します。また、メモリ内で gen0、gen1、gen2 (ジェネレーション) と呼ばれる 3 つの「ピース」に大まかに分けられます。

gen0 では、割り当てられたメモリが小さい高速なオブジェクトが存在します。ガベージ コレクションは、存続期間の短いオブジェクトが多数あるため、頻繁に実行されます。オブジェクトが gen0 を生き残った場合、それは次の世代に移動されます。

オブジェクトがガベージ コレクションされると、他のすべてのオブジェクトがメモリ内で再配置され、使用可能な空きメモリ領域が維持されます。

しかし、最大かつ長寿命のオブジェクトが存在する gen2 では、gen2 でオブジェクトを移動するにはコストがかかりすぎるため、メモリが再配置されることはめったにありません。

このすべてのメモリ参照とガベージ コレクションは、C# のような管理された環境で「無料」で提供されます。

さらに、「文字列インターン」などの最適化が行われることもあります。

于 2012-09-28T17:26:51.967 に答える